home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Misc / NeXTcontour_1.7 / Source / Contour.m < prev    next >
Encoding:
Text File  |  1995-06-12  |  102.0 KB  |  3,854 lines

  1.  
  2. /* Generated by Interface Builder */
  3.  
  4. #import "defs.h"
  5. #import "Contour.h"
  6. #import <appkit/Button.h>
  7. #import <appkit/OpenPanel.h>
  8. #import <appkit/Matrix.h>
  9. #import <appkit/Cell.h>
  10. #import <appkit/Pasteboard.h>
  11. #import <appkit/Application.h>
  12. #import <appkit/NXColorWell.h>
  13. #import <appkit/color.h>
  14. #import <objc/Storage.h>
  15. #import <math.h>
  16. #import <strings.h>
  17. #import <defaults/defaults.h>
  18. #import <streams/streams.h>
  19. #import <sys/types.h>
  20. #import <sys/stat.h>
  21. #import "TextView.h"
  22.  
  23. @implementation Contour
  24.  
  25. /* Public methods */
  26.  
  27. + initialize
  28. /* Initializes the defaults. */
  29. {
  30.     const NXDefaultsVector NeXTcontourDefaults = {
  31.     { "Two_D", "NO" },
  32.         { "AeroDynamics", "YES"},
  33.         { "Binary_Data", "YES"},
  34.         { "number_Of_Functions_Read_In", "5"},
  35.         { "colorOption", "NO"},
  36.         { "printColorMode", "NO"},
  37.     { NULL, NULL }
  38.     };
  39.       
  40.     NXRegisterDefaults("NeXTcontour", NeXTcontourDefaults);
  41.  
  42.     return self;
  43.   }
  44.  
  45. + new
  46. {
  47.   const char *validSendTypes[2];
  48.  
  49.   self = [[super alloc] init];
  50.   openPanel  = [OpenPanel new];
  51.  
  52.   validSendTypes[0] = NXAsciiPboardType;
  53.   validSendTypes[1] = NULL;
  54.   [NXApp registerServicesMenuSendTypes:validSendTypes andReturnTypes:NULL];
  55.   [NXApp setDelegate:self];
  56.   return self;
  57. }
  58.  
  59. - appWillInit:sender
  60. {
  61.  
  62.   /*  get default parameters and reset buttons */
  63.  
  64.   NXUpdateDefaults();
  65.  
  66.   /* Initialize defaults */
  67.   Two_D = strncmp(NXGetDefaultValue("NeXTcontour", "Two_D"),"YES",3)==0 ?
  68.   YES: NO;
  69.  
  70.   number_Of_Functions_Read_In = 
  71.     strncmp(NXGetDefaultValue("NeXTcontour", "number_Of_Functions_Read_In"),
  72.         "4",3) ==0 ? 4: 1;
  73.  
  74.   colorOption = strncmp(NXGetDefaultValue("NeXTcontour", "colorOption"),
  75.             "YES",3)==0 ? YES: NO;
  76.  
  77.   printColorMode = 
  78.     strncmp(NXGetDefaultValue("NeXTcontour", "printColorMode"),
  79.         "YES",3)==0 ? YES: NO;
  80.  
  81.   AeroDynamic_Functions = 
  82.     strncmp(NXGetDefaultValue("NeXTcontour", "AeroDynamics"),
  83.             "YES",3)==0 ? YES: NO;
  84.  
  85.   Binary_Data_Type = 
  86.     strncmp(NXGetDefaultValue("NeXTcontour", "Binary_Data"),
  87.             "YES",3)==0 ? YES: NO;
  88.  
  89.   if(Two_D){
  90.     [choose2D3DData setState:1];
  91.     [choose2D3DGrid setState:1];
  92.     [setDefault2D3D  setState:1];
  93.     if(AeroDynamic_Functions){
  94.       [setDefaultNumberOfFunctions setIntValue:4 at:0];
  95.       [numberOfFunctions setIntValue:4 at:0];
  96.       number_Of_Functions_Read_In = 4;
  97.     }
  98.   }
  99.  
  100.   if(!Two_D){
  101.     [choose2D3DData setState:0];
  102.     [choose2D3DGrid setState:0];
  103.     [setDefault2D3D  setState:0];
  104.     if(AeroDynamic_Functions){
  105.       [setDefaultNumberOfFunctions setIntValue:5 at:0];
  106.       [numberOfFunctions setIntValue:5 at:0];
  107.       number_Of_Functions_Read_In = 5;
  108.     }
  109.   }
  110.  
  111.   if(AeroDynamic_Functions){
  112.     [chooseDiscipline setState:0];
  113.     [setDefaultDiscipline setState:0];
  114.   }
  115.  
  116.   if(!AeroDynamic_Functions){
  117.     [chooseDiscipline setState:1];
  118.     [setDefaultDiscipline setState:1];
  119.     [setDefaultNumberOfFunctions setIntValue:number_Of_Functions_Read_In at:0];
  120.     [numberOfFunctions setIntValue:number_Of_Functions_Read_In at:0];
  121.   }
  122.  
  123.   if(Binary_Data_Type){
  124.     [chooseDataType setState:0];
  125.     [setDefaultDataForm setState:0];
  126.   }
  127.  
  128.   if(!Binary_Data_Type){
  129.     [chooseDataType setState:1];
  130.     [setDefaultDataForm setState:1];
  131.   }
  132.  
  133.   if(colorOption){
  134.     [setDefaultColor setState:0];
  135.     [contourLineColor selectCellAt:0:3];
  136.   }
  137.   if(!colorOption){
  138.     [setDefaultColor setState:1];
  139.     [contourLineColor selectCellAt:0:2];
  140.   }
  141.  
  142.   if(printColorMode){
  143.     [setDefaultPrintColor setState:1];
  144.     [printColor setState:1];
  145.   }
  146.   if(!printColorMode){
  147.     [setDefaultPrintColor setState:0];
  148.     [printColor setState:0];
  149.   }
  150.  
  151.   [setDefault2D3D display];
  152.   [setDefaultColor display];
  153.   [setDefaultPrintColor display];
  154.   [printColor display];
  155.   [setDefaultDiscipline display];
  156.   [chooseDiscipline display];
  157.   [choose2D3DData display];
  158.   [choose2D3DGrid display];
  159.  
  160.   if(colorOption)
  161.     {
  162.       [backgroundColor setColor:NX_COLORBLACK];
  163.       [foregroundColor setColor:NX_COLORWHITE];
  164.       [gridLineColor   setColor:NX_COLORLTGRAY];
  165.     }
  166.   if(!colorOption)
  167.     {
  168.       [foregroundColor setColor:NX_COLORBLACK];
  169.       [backgroundColor setColor:NX_COLORWHITE];
  170.       [gridLineColor   setColor:NX_COLORLTGRAY];
  171.     }
  172.  
  173.   gridIsReadIn = NO;
  174.   solutionIsReadIn = NO;
  175.   oldMin.x = 0.0;
  176.   oldMin.y = 0.0;
  177.   oldMax.x = 1.0;
  178.   oldMax.y = 1.0;
  179.   currentMin.x = 0.0;
  180.   currentMin.y = 0.0;
  181.   currentMax.x = 1.0;
  182.   currentMax.y = 1.0;
  183.  
  184.   [canvasWindow getFrame:&oldFrame];
  185.  
  186.   return self;
  187. }
  188.  
  189. - appDidInit:sender
  190. {
  191.   [canvasWindow     setMiniwindowIcon:"NeXTcontour.tiff"];
  192.   [controlsPanel    setMiniwindowIcon:"NeXTcontour.tiff"];
  193.   [preferencesPanel setMiniwindowIcon:"NeXTcontour.tiff"];
  194.   [subsetsPanel     setMiniwindowIcon:"NeXTcontour.tiff"];
  195.   [colorPanel       setMiniwindowIcon:"NeXTcontour.tiff"];
  196.   [helpPanel        setMiniwindowIcon:"NeXTcontour.tiff"];
  197.   [levelsPanel      setMiniwindowIcon:"NeXTcontour.tiff"];
  198.  
  199.   return self;
  200. }
  201.  
  202. - resetDefaults:sender
  203. {
  204.   int s1 = [setDefault2D3D state];
  205.   int s2 = [setDefaultDiscipline state];
  206.   int s3 = [setDefaultColor state];
  207.   int s4 = [setDefaultPrintColor state];
  208.   int s5 = [setDefaultDataForm state];
  209.   char s[4];
  210.  
  211.   s[0] = '5';
  212.   s[1] = '\0';
  213.   s[2] = '\0';
  214.   s[3] = '\0';
  215.  
  216.   switch(s1){
  217.   case 0:
  218.     Two_D = NO;
  219.     NXWriteDefault("NeXTcontour", "Two_D", "NO");
  220.     [choose2D3DData setState:0];
  221.     [choose2D3DGrid setState:0]; 
  222.    break;
  223.   case 1:
  224.     Two_D = YES;
  225.     NXWriteDefault("NeXTcontour", "Two_D", "YES");
  226.     [choose2D3DData setState:1];
  227.     [choose2D3DGrid setState:1];
  228.     break;
  229.   }
  230.  
  231.   switch(s2){
  232.   case 0:
  233.     AeroDynamic_Functions = YES;
  234.     NXWriteDefault("NeXTcontour", "AeroDynamics", "YES");
  235.     [chooseDiscipline setState:0];
  236.     if(Two_D){
  237.       [setDefaultNumberOfFunctions setIntValue:4 at:0];
  238.       number_Of_Functions_Read_In = 4;
  239.       [numberOfFunctions setIntValue:4 at:0];
  240.       NXWriteDefault("NeXTcontour", "number_Of_Functions_Read_In", "4");
  241.     }
  242.     if(!Two_D){
  243.       [setDefaultNumberOfFunctions setIntValue:5 at:0];
  244.       number_Of_Functions_Read_In = 5;
  245.       [numberOfFunctions setIntValue:5 at:0];
  246.       NXWriteDefault("NeXTcontour", "number_Of_Functions_Read_In", "5");
  247.     }
  248.     break;
  249.   case 1:
  250.     AeroDynamic_Functions = NO;
  251.     [chooseDiscipline setState:1];
  252.     NXWriteDefault("NeXTcontour", "AeroDynamics", "NO");
  253.     number_Of_Functions_Read_In = [setDefaultNumberOfFunctions intValueAt:0];
  254.     [numberOfFunctions setIntValue:number_Of_Functions_Read_In at:0];
  255.     sprintf(s,"%d",number_Of_Functions_Read_In);
  256.     NXWriteDefault("NeXTcontour", "number_Of_Functions_Read_In", s);
  257.     break;
  258.   }
  259.   
  260.   switch(s3){
  261.   case 0:
  262.     colorOption = YES;
  263.     NXWriteDefault("NeXTcontour", "colorOption", "YES");
  264.     [contourLineColor selectCellAt:0:3];
  265.     break;
  266.   case 1:
  267.     colorOption = NO;
  268.     NXWriteDefault("NeXTcontour", "colorOption", "NO");
  269.     [contourLineColor selectCellAt:0:2];
  270.     break;
  271.   }
  272.  
  273.   switch(s4){
  274.   case 0:
  275.     printColorMode = NO;
  276.     NXWriteDefault("NeXTcontour", "printColorMode", "NO");
  277.     [printColor setState:0];
  278.     break;
  279.   case 1:
  280.     printColorMode = YES;
  281.     NXWriteDefault("NeXTcontour", "printColorMode", "YES");
  282.     [printColor setState:1];
  283.     break;
  284.   }
  285.  
  286.   switch(s5){
  287.   case 0:
  288.     Binary_Data_Type = YES;
  289.     NXWriteDefault("NeXTcontour", "Binary_Data", "YES");
  290.     [chooseDataType setState:0];
  291.     break;
  292.   case 1:
  293.     Binary_Data_Type = NO;
  294.     NXWriteDefault("NeXTcontour", "Binary_Data", "NO");
  295.     [chooseDataType setState:1];
  296.     break;
  297.   }
  298.   
  299.   [printColor display];
  300.   [choose2D3DData display];
  301.   [choose2D3DGrid display];
  302.   [chooseDataType display];
  303.   [chooseDiscipline display];
  304.   [contourLineColor display];
  305.  
  306.   return self;
  307. }
  308.  
  309. - validRequestorForSendType:(NXAtom)sendType andReturnType:(NXAtom)returnType
  310. {
  311.   NXAtom a;
  312.   a = NXUniqueString(NXAsciiPboardType);
  313.   return (a==sendType)? self :nil;
  314. }
  315.  
  316. - writeSelectionToPasteboard:pboard types:(NXAtom *)types
  317. {
  318.   int i;
  319.   NXStream *my_stream;
  320.   int length, max_length;
  321.   char *data;
  322.  
  323.   my_stream = NXOpenMemory(NULL,0,NX_WRITEONLY);
  324.   for (i = 0; i < xyData.jmax; i++){
  325.     NXPrintf(my_stream,"%g %g \n", xyData.x[i], xyData.f[i]);
  326.   }
  327.  
  328.   NXGetMemoryBuffer(my_stream, &data, &length, &max_length);
  329.  
  330.   [pboard declareTypes:&NXAsciiPboardType num:1 owner:self];
  331.   [pboard writeType:NXAsciiPboardType data:data length:length];
  332.  
  333.   NXCloseMemory(my_stream, NX_TRUNCATEBUFFER);
  334.   return self;
  335. }
  336.  
  337. - (const char *)provideMainTitle   { return [mainTitle stringValueAt:0]; }
  338. - (const char *)provideFunctionTitle{ return [functionTitle stringValueAt:0];}
  339.  
  340. - (float)provideGridLineThickness { return [gridLineThickness floatValue]; }
  341. - (float)provideContourLineThickness{return [contourLineThickness floatValue];}
  342. - (NXCoord *)provideContourLevels:sender {  return contourLevels; }
  343.  
  344. - (NXColor) provideGridLineColor
  345.   if ((NXDrawingStatus == NX_PRINTING  && [printColor state] == 0) 
  346.       || ([printPreviewMode state] != 0 && [printColor state] == 0)){
  347.     if([gridLineColorMatrix selectedCol] == 0)return NX_COLORLTGRAY;
  348.     if([gridLineColorMatrix selectedCol] == 1)return NX_COLORDKGRAY;
  349.     if([gridLineColorMatrix selectedCol] == 2)return NX_COLORBLACK;
  350.   }
  351.   else{
  352.     if(colorOption){
  353.       return [gridLineColor color];
  354.     }
  355.     else {
  356.       if([gridLineColorMatrix selectedCol] == 0)return NX_COLORLTGRAY;
  357.       if([gridLineColorMatrix selectedCol] == 1)return NX_COLORDKGRAY;
  358.       if([gridLineColorMatrix selectedCol] == 2)return NX_COLORBLACK;
  359.     }
  360.   }
  361.   return NX_COLORBLACK;        // Never reached, put in to eliminate Compiler Warning
  362. }
  363.  
  364. - (NXColor) provideBackGroundColor
  365. {
  366.   if ((NXDrawingStatus == NX_PRINTING  && [printColor state] == 0)
  367.       || ([printPreviewMode state] != 0 && [printColor state] == 0)){
  368.     return NX_COLORWHITE;
  369.   }
  370.   else{
  371.     return [backgroundColor color];
  372.   }
  373. }
  374.  
  375. - (NXColor) provideForeGroundColor
  376. {
  377.   if (((NXDrawingStatus == NX_PRINTING  && [printColor state] == 0) 
  378.       || ([printPreviewMode state] != 0 && [printColor state] == 0))){
  379.     return NX_COLORBLACK;
  380.   }
  381.   else{
  382.     return [foregroundColor color];
  383.   }
  384. }
  385.  
  386. - (int) provideContourLineColor     
  387. {
  388.   int i = 2;
  389.   if ((NXDrawingStatus == NX_PRINTING  && [printColor state] == 0) 
  390.       || ([printPreviewMode state] != 0 && [printColor state] == 0)){
  391.     return i;
  392.   }
  393.   else{
  394.     if(!colorOption && [contourLineColor selectedCol]==3){
  395.       NXBeep();    beepError = 25;    /* audible alert */
  396.       [contourLineColor selectCellAt:0:2];
  397.     }
  398.     return [contourLineColor selectedCol]; 
  399.   }
  400. }
  401.  
  402. - (int) provideContourNumber:sender { return contourNumber;}
  403. - (int) provideViewingChoice:sender 
  404.                    {return [viewingTransformations selectedRow] + 4*
  405.               [viewingTransformations selectedCol]; }
  406. - (int) provideViewPoint:sender 
  407.                    {return [viewPoint state]; }
  408. - (int) provideFunctionChoice:sender
  409.                    { return [functionMatrix selectedRow];}
  410.  
  411. - (function_part)provideFunction:sender { return functionH; }
  412. - (grid_part)    provideGrid:sender     { return gridH; }
  413.  
  414.  
  415. - (NXCoord)provideFsmach { return solnhunk.fsmach; }
  416. - (NXCoord)provideAlpha  { return solnhunk.alpha; }
  417. - (NXCoord)provideRe     { return solnhunk.re; }
  418. - (NXCoord)provideTime   { return solnhunk.time; }
  419.  
  420. - (NXCoord)provideContourmin  {return [contourLimits floatValueAt:0];}
  421. - (NXCoord)provideContourmax  {return [contourLimits floatValueAt:1];}
  422. - (NXCoord)provideContourinc  {return [contourLimits floatValueAt:2];}
  423. - (NXCoord)provideFmin  {return [fMin floatValueAt:0];}
  424. - (NXCoord)provideFmax  {return [fMax floatValueAt:0];}
  425. - (NXCoord)provideXmin  {return [xyLimits floatValueAt:0];}
  426. - (NXCoord)provideXmax  {return [xyLimits floatValueAt:1];}
  427. - (NXCoord)provideYmin  {return [xyLimits floatValueAt:2];}
  428. - (NXCoord)provideYmax  {return [xyLimits floatValueAt:3];}
  429.  
  430. - (BOOL) doAnimateF
  431. {  if ( [animate3DFOnOff state] ) return YES;  else return NO; }
  432. - (BOOL) doAnimateG
  433. {  if ( [animate3DGOnOff state] ) return YES;  else return NO; }
  434.  
  435. - (BOOL) doSetAspectRatio
  436. {  if ( [setAspectRatio state] ) return NO;  else return YES; }
  437.  
  438. - (BOOL) do2D3D 
  439. {  if ( [choose2D3DData state] ) return YES;  else return NO; }
  440. - (BOOL) do2D3D_grid 
  441. {  if ( [choose2D3DGrid state] ) return YES;  else return NO; }
  442.  
  443. - (BOOL) doAeroDynamics 
  444. {  if ( [chooseDiscipline state] ) return NO;  else return YES; }
  445.  
  446.  
  447. - (BOOL) shouldChangeTitleFont
  448. {  if ( [changeTitleFont state] ) return YES;   else return NO; }
  449.  
  450. - (BOOL) shouldChangeLabelFont
  451. {  if ( [changeLabelFont state] ) return YES;   else return NO; }
  452.  
  453. - (BOOL) shouldShowXYLabels
  454. {  if ( [xyLabelsOn state] ) return YES;   else return NO; }
  455.  
  456. - (BOOL) shouldShowUnitsLabel
  457. {  if ( [unitsLabelOn state] ) return YES;   else return NO; }
  458.  
  459. - (BOOL) shouldShowContourValues
  460. {  if ( [contourValuesOn state] ) return YES;   else return NO; }
  461.  
  462. - (BOOL) doZoom
  463. {  if ( [zoomOnOff state] ) return YES;  else return NO; }
  464.  
  465. - (BOOL) doDrawFunction
  466. {  if ( [drawFunction state] ) return YES;   else return NO; }
  467.  
  468. - (BOOL) doDrawGrid
  469. {  if ( [drawGrid state] ) return YES;   else return NO; }
  470.  
  471. - (BOOL) doClearPlot
  472. {  if ( [clearPlot state] ) return NO;   else return YES; }
  473.  
  474. - (BOOL) doSolidLines
  475. {  if ( [solidContourLines state] ) return NO;   else return YES; }
  476.  
  477.  
  478. - resetCmin:(NXCoord)aNum { [contourLimits setFloatValue:aNum at:0]; 
  479.                 return self; }
  480. - resetCmax:(NXCoord)aNum { [contourLimits setFloatValue:aNum at:1]; 
  481.                 return self; }
  482. - resetCinc:(NXCoord)aNum { [contourLimits setFloatValue:aNum at:2]; 
  483.                 return self; }
  484. - resetFmin:(NXCoord)aNum { [fMin setFloatValue:aNum at:0]; return self; }
  485. - resetFmax:(NXCoord)aNum { [fMax setFloatValue:aNum at:0]; return self; }
  486. - resetXmin:(NXCoord)aNum { [xyLimits setFloatValue:aNum at:0]; return self; }
  487. - resetXmax:(NXCoord)aNum { [xyLimits setFloatValue:aNum at:1]; return self; }
  488. - resetYmin:(NXCoord)aNum { [xyLimits setFloatValue:aNum at:2]; return self; }
  489. - resetYmax:(NXCoord)aNum { [xyLimits setFloatValue:aNum at:3]; return self; }
  490.  
  491. -resetMinMax:sender
  492. {
  493.   if([self doDrawGrid] && ![self doDrawFunction]){
  494.     if(gridhunk.jmax != 0) [self loadGrid:self];
  495.     [self findGridMinAndMax];
  496.     [self resetGridMinMax:self];
  497.   }
  498.   if([self doDrawFunction]){
  499.     [self loadFunctionGrid:self];
  500.     [self findFunctionGridMinAndMax];
  501.     [self resetFunctionGridMinMax:self];
  502.   }
  503.   return self;
  504. }
  505.  
  506.  
  507. - resetGridMinMax:sender
  508. {
  509.   [self resetXmin:gridH.gridmin.x];
  510.   [self resetYmin:gridH.gridmin.y];
  511.   [self resetXmax:gridH.gridmax.x];
  512.   [self resetYmax:gridH.gridmax.y];
  513.   currentMin.x = gridH.gridmin.x;
  514.   currentMin.y = gridH.gridmin.y;
  515.   currentMax.x = gridH.gridmax.x;
  516.   currentMax.y = gridH.gridmax.y;
  517.   
  518.   return self;
  519. }
  520.  
  521. - resetFunctionGridMinMax:sender
  522. {
  523.   [self resetXmin:functionH.gridmin.x];
  524.   [self resetYmin:functionH.gridmin.y];
  525.   [self resetXmax:functionH.gridmax.x];
  526.   [self resetYmax:functionH.gridmax.y];
  527.   currentMin.x = functionH.gridmin.x;
  528.   currentMin.y = functionH.gridmin.y;
  529.   currentMax.x = functionH.gridmax.x;
  530.   currentMax.y = functionH.gridmax.y;
  531.   return self;
  532. }
  533.  
  534. - resetFunctionMinMax:sender
  535. {
  536.   [self resetFmin:functionH.functionmin];
  537.   [self resetFmax:functionH.functionmax];
  538.   return self;
  539. }
  540.  
  541. - resetGridSubsets:sender
  542. {
  543.   int i = 1;
  544.  
  545.     [jGridMax setIntValue:gridhunk.jmax at:0];
  546.     [kGridMax setIntValue:gridhunk.kmax at:0];
  547.     [lGridMax setIntValue:gridhunk.lmax at:0];
  548.     [jGridMin setIntValue:i at:0];
  549.     [kGridMin setIntValue:i at:0];
  550.     [lGridMin setIntValue:i at:0];
  551.     [jGridInc setIntValue:i at:0];
  552.     [kGridInc setIntValue:i at:0];
  553.     [lGridInc setIntValue:i at:0];
  554.  
  555.     return self;
  556. }
  557.  
  558.  
  559. - resetFunctionSubsets:sender
  560. {
  561.   int i = 1;
  562.     [jFunctionMax setIntValue:solnhunk.jmax at:0];
  563.     [kFunctionMax setIntValue:solnhunk.kmax at:0];
  564.     [lFunctionMax setIntValue:solnhunk.lmax at:0];
  565.     [jFunctionMin setIntValue:i at:0];
  566.     [kFunctionMin setIntValue:i at:0];
  567.     [lFunctionMin setIntValue:i at:0];
  568.     [jFunctionInc setIntValue:i at:0];
  569.     [kFunctionInc setIntValue:i at:0];
  570.     [lFunctionInc setIntValue:i at:0];
  571.     return self;
  572. }
  573.  
  574. - resetLineSubsets:sender
  575. {
  576.   int i = 1;
  577.   int lineChoice = [chooseLineData selectedRow];
  578.   BOOL b_2D = [self do2D3D];
  579.   
  580.   if(b_2D){
  581.     if(lineChoice == 2 ){
  582.       NXBeep();    beepError = 24;    /* audible alert */
  583.       lineChoice = 0;
  584.       [chooseLineData selectCellAt:lineChoice:0];
  585.     }
  586.   }
  587.  
  588.   switch(lineChoice){
  589.   case 0:
  590.     [jLineMax setIntValue:gridhunk.jmax at:0];
  591.     [kLineMax setIntValue:i at:0];
  592.     [lLineMax setIntValue:i at:0];
  593.     break;
  594.   case 1:
  595.     [kLineMax setIntValue:gridhunk.kmax at:0];
  596.     [jLineMax setIntValue:i at:0];
  597.     [lLineMax setIntValue:i at:0];
  598.     break;
  599.   case 2:
  600.     [lLineMax setIntValue:gridhunk.lmax at:0];
  601.     [kLineMax setIntValue:i at:0];
  602.     [jLineMax setIntValue:i at:0];
  603.     break;
  604.   }
  605.  
  606.   [jLineMin setIntValue:i at:0];
  607.   [kLineMin setIntValue:i at:0];
  608.   [lLineMin setIntValue:i at:0];
  609.   [jLineInc setIntValue:i at:0];
  610.   [kLineInc setIntValue:i at:0];
  611.   [lLineInc setIntValue:i at:0];
  612.   
  613.   return self;
  614. }
  615.  
  616. - resetAll:sender
  617. {
  618.   [self resetGridSubsets:self];
  619.   [self resetFunctionSubsets:self];
  620.   [self resetFunctionMinMax:self];
  621.   stateChangeGrid = YES;
  622.   stateChangeFunction = YES;
  623.   return self;
  624. }
  625.  
  626. - resetProjectionData:sender{  
  627.   stateChangeGrid = YES;  
  628.   stateChangeFunction = YES;  
  629.   return self;
  630. }
  631.  
  632. - resetGridLineColorWell:sender{  
  633.   if([gridLineColorMatrix selectedCol] == 0)
  634.     [gridLineColor   setColor:NX_COLORLTGRAY];
  635.   if([gridLineColorMatrix selectedCol] == 1)
  636.     [gridLineColor   setColor:NX_COLORDKGRAY];
  637.   if([gridLineColorMatrix selectedCol] == 2)
  638.     [gridLineColor   setColor:NX_COLORBLACK];
  639.   [gridLineColor display];
  640.   return self;
  641. }
  642.  
  643. - resetGridData:sender{  
  644.   [self resetGridSubsets:self];
  645.   stateChangeGrid = YES;  
  646.   return self;
  647. }
  648.  
  649. - resetLineData:sender{  
  650.   [self resetLineSubsets:self];
  651.   return self;
  652. }
  653.  
  654. - resetFunctionData:sender{  
  655.   [self resetFunctionSubsets:self];
  656.   stateChangeFunction = YES;  
  657.   return self;
  658. }
  659.  
  660. - eQuateSubsets:sender{
  661.   BOOL b_2D_grid = [self do2D3D_grid];
  662.   [jGridMin setIntValue:[jFunctionMin intValueAt:0] at:0];
  663.   [jGridMax setIntValue:[jFunctionMax intValueAt:0] at:0];
  664.   [jGridInc setIntValue:[jFunctionInc intValueAt:0] at:0];
  665.   [kGridMin setIntValue:[kFunctionMin intValueAt:0] at:0];
  666.   [kGridMax setIntValue:[kFunctionMax intValueAt:0] at:0];
  667.   [kGridInc setIntValue:[kFunctionInc intValueAt:0] at:0];
  668.   if(!b_2D_grid){
  669.     [lGridMin setIntValue:[lFunctionMin intValueAt:0] at:0];
  670.     [lGridMax setIntValue:[lFunctionMax intValueAt:0] at:0];
  671.     [lGridInc setIntValue:[lFunctionInc intValueAt:0] at:0];
  672.   }
  673.   if(b_2D_grid){
  674.     [lGridMin setIntValue:1 at:0];
  675.     [lGridMax setIntValue:1 at:0];
  676.     [lGridInc setIntValue:1 at:0];
  677.   }
  678.   [chooseGridPlane selectCellAt:[chooseFunctionPlane selectedRow]:0];
  679.   return self;
  680. }
  681.  
  682. - drawPlotButton:(int)state
  683. {
  684.   if (state==0) {
  685.     [plotButton highlight:NO];    /* will display normal title */
  686.   }
  687.   if (state==1) {
  688.     [plotButton highlight:YES];    /* will display alternate title */
  689.   }
  690.   return self;
  691. }
  692.  
  693.  
  694. - makeContourLevels:sender
  695. {
  696.   float fmin,fmax,finc;
  697.   int   ncont = 0,n;
  698.  
  699.   if( ![autoContours state] ){
  700.     
  701.     fmin  = [fMin floatValueAt:0];
  702.     fmax  = [fMax floatValueAt:0];
  703.     ncont = [numberContours intValueAt:0];
  704.     
  705.     if(ncont == 0){
  706.       ncont = 1;
  707.       [numberContours setIntValue:ncont at:0];
  708.     }
  709.  
  710.     finc = (fmax-fmin)/20.;
  711.     if(ncont != 1)finc = (fmax - fmin)/(ncont-1);
  712.     if(ncont == 1)finc = 0.0;
  713.  
  714.     [self resetCmin:fmin];    /* send contour level info to panel */
  715.     [self resetCmax:fmax];
  716.     [self resetCinc:finc];
  717.  
  718.     contourNumber = ncont;
  719.     free(contourLevels);
  720.     contourLevels = (NXCoord *)malloc(ncont*sizeof(float));
  721.  
  722.     for (n=0; n < ncont; n++){
  723.       contourLevels[n] = fmin + n*finc;
  724.     }
  725.   }
  726.   
  727.   else{
  728.  
  729.     fmin = [contourLimits floatValueAt:0];
  730.     fmax = [contourLimits floatValueAt:1];
  731.     finc = [contourLimits floatValueAt:2];
  732.  
  733.     if(finc == 0.0 && (fmax != fmin) ){
  734.       ncont = [numberContours intValueAt:0];
  735.       finc = (fmax-fmin)/ncont;
  736.       [self resetCinc:finc];
  737.     }
  738.  
  739.     if(finc != 0)ncont = (int)(ABS(fmax - fmin)/ABS(finc));
  740.     if(fmin + ncont*finc != fmax)ncont = ncont + 1;
  741.     if(fmin == fmax)ncont = 1;
  742.  
  743.     contourNumber = ncont;
  744.     free(contourLevels);
  745.     contourLevels = (NXCoord *)malloc(ncont*sizeof(float));
  746.  
  747.     for (n=0; n < ncont; n++){
  748.       contourLevels[n] = fmin + n*finc;
  749.     }
  750.     if(contourLevels[ncont-1] > fmax)contourLevels[ncont-1] = fmax;
  751.   }
  752.   
  753.   return self;
  754. }
  755.  
  756.  
  757. - drawPlot:sender
  758. {
  759.   /* get new subsets and function for plotting */
  760.  
  761.   BOOL animateF = [self doAnimateF];
  762.   BOOL animateG = [self doAnimateG];
  763.   BOOL b_2D = [self do2D3D];
  764.   int planeChoice = [chooseFunctionPlane selectedRow];
  765.   int i, i_0 = 0, i_m = 1, i_i = 1;
  766.   char c_xmin[20],c_xmax[20],c_ymin[20],c_ymax[20];
  767.   float xmin,xmax,ymin,ymax;
  768.  
  769.   /* error check */
  770.   if(animateF && ![self doDrawFunction])
  771.     {NXBeep(); beepError = 1; return self; }
  772.   if(animateG && ![self doDrawGrid])
  773.     {NXBeep(); beepError = 1; return self; }
  774.  
  775.   if([self doDrawGrid] && gridH.jmax == 0)
  776.     { NXBeep(); beepError = 2; return self; }
  777.  
  778.   if([self doDrawFunction] && functionH.jmax == 0)
  779.     {NXBeep(); beepError = 3; return self; }
  780.  
  781. /*  Need to convert the floating point vlaues of currentMin/Max to strings
  782.     and back to floats because: when TextFields are read the floating point 
  783.     values in the textfield is converted from a sting to a float.  If this is 
  784.     not done then the absolute comparison of the floating points values, (e.g.
  785.     currentMin.x != [xyLimits floatValueAt:0] ) will fail because of conversion
  786.     errors, causing all types of problems.  thp 1/10/92 
  787. */
  788.  
  789.   sprintf(c_xmin,"%g",currentMin.x);
  790.   sprintf(c_xmax,"%g",currentMax.x);
  791.   sprintf(c_ymin,"%g",currentMin.y);
  792.   sprintf(c_ymax,"%g",currentMax.y);
  793.   xmin = (float)atof(c_xmin);
  794.   ymin = (float)atof(c_ymin);
  795.   xmax = (float)atof(c_xmax);
  796.   ymax = (float)atof(c_ymax);
  797.  
  798.   if ( xmin != [xyLimits floatValueAt:0] 
  799.       || xmax != [xyLimits floatValueAt:1]
  800.       || ymin != [xyLimits floatValueAt:2]
  801.       || ymax != [xyLimits floatValueAt:3] ) {
  802.     oldMin.x = currentMin.x;
  803.     currentMin.x = [xyLimits floatValueAt:0];
  804.     oldMax.x = currentMax.x;
  805.     currentMax.x = [xyLimits floatValueAt:1];
  806.     oldMin.y = currentMin.y;
  807.     currentMin.y = [xyLimits floatValueAt:2];
  808.     oldMax.y = currentMax.y;
  809.     currentMax.y = [xyLimits floatValueAt:3];
  810.   }
  811.  
  812.   if(animateF && animateG)[self eQuateSubsets:self];
  813.  
  814.   if([printPreviewMode state] !=0){   /*  if preview mode reset clearplot */
  815.     [clearPlot setState:0];    [clearPlot display];
  816.   }
  817.  
  818.   /* function choices always take precedence over grid choices */
  819.   if(animateG && !animateF)planeChoice = [chooseGridPlane selectedRow];
  820.   if(animateF)planeChoice =              [chooseFunctionPlane selectedRow]; 
  821.  
  822.   switch(planeChoice){
  823.   case 0:
  824.     if(animateG && !animateF){
  825.       i_0 = [jGridMin intValueAt:0]-1;
  826.       i_i = [jGridInc intValueAt:0];
  827.       if(i_i <= 0){
  828.     NXBeep(); beepError = 26; 
  829.     i_i = 1;
  830.     [jGridInc setIntValue:i_i at:0];
  831.     return self; }
  832.       i_m = [jGridMax intValueAt:0]-1;
  833.     }
  834.     if(animateF){
  835.       i_0 = [jFunctionMin intValueAt:0]-1;
  836.       i_i = [jFunctionInc intValueAt:0];
  837.       if(i_i <= 0){
  838.     NXBeep(); beepError = 26; 
  839.     i_i = 1;
  840.     [jFunctionInc setIntValue:i_i at:0];
  841.     return self; }
  842.       i_m = [jFunctionMax intValueAt:0]-1;
  843.     }
  844.     break;
  845.   case 1:
  846.     if(animateG && !animateF){
  847.       i_0 = [kGridMin intValueAt:0]-1;
  848.       i_i = [kGridInc intValueAt:0];
  849.       if(i_i <= 0){
  850.     NXBeep(); beepError = 26; 
  851.     i_i = 1;
  852.     [kGridInc setIntValue:i_i at:0];
  853.     return self; }
  854.       i_m = [kGridMax intValueAt:0]-1;
  855.     }
  856.     if(animateF){
  857.       i_0 = [kFunctionMin intValueAt:0]-1;
  858.       i_i = [kFunctionInc intValueAt:0];
  859.       if(i_i <= 0){
  860.     NXBeep(); beepError = 26; 
  861.     i_i = 1;
  862.     [kFunctionInc setIntValue:i_i at:0];
  863.     return self; }
  864.       i_m = [kFunctionMax intValueAt:0]-1;
  865.     }
  866.     break;
  867.   case 2:
  868.     if(animateG && !animateF){
  869.       i_0 = [lGridMin intValueAt:0]-1;
  870.       i_i = [lGridInc intValueAt:0];
  871.       if(i_i <= 0){
  872.     NXBeep(); beepError = 26; 
  873.     i_i = 1;
  874.     [lGridInc setIntValue:i_i at:0];
  875.     return self; }
  876.       i_m = [lGridMax intValueAt:0]-1;
  877.     }
  878.     if(animateF){
  879.       i_0 = [lFunctionMin intValueAt:0]-1;
  880.       i_i = [lFunctionInc intValueAt:0];
  881.       if(i_i <= 0){
  882.     NXBeep(); beepError = 26; 
  883.     i_i = 1;
  884.     [lFunctionInc setIntValue:i_i at:0];
  885.     return self; }
  886.       i_m = [lFunctionMax intValueAt:0]-1;
  887.     }
  888.     break;
  889.   }
  890.  
  891.   if(b_2D || (!animateF && !animateG)){    i_i = 1;    i_m = i_0;   }
  892.  
  893.  
  894.   for (i = i_0; i <= i_m; i+= i_i){
  895.  
  896.     if(animateG){
  897.       switch(planeChoice){
  898.       case 0:
  899.     [jGridMin setIntValue:i+1 at:0];
  900.     break;
  901.       case 1:
  902.     [kGridMin setIntValue:i+1 at:0];
  903.     break;
  904.       case 2:
  905.     [lGridMin setIntValue:i+1 at:0];
  906.     break;
  907.       }
  908.     }
  909.     if([self doDrawGrid])[self loadGrid:self];
  910.  
  911.     if(animateF){
  912.       switch(planeChoice){
  913.       case 0:
  914.     [jFunctionMin setIntValue:i+1 at:0];
  915.     break;
  916.       case 1:
  917.     [kFunctionMin setIntValue:i+1 at:0];
  918.     break;
  919.       case 2:
  920.     [lFunctionMin setIntValue:i+1 at:0];
  921.     break;
  922.       }
  923.     }
  924.     if(solutionIsReadIn && [self doDrawFunction]){
  925.       [self loadFunctionGrid:self];
  926.       [self loadFunction:self];
  927.       [self makeContourLevels:self];
  928.     }
  929.       
  930.     if([self doDrawFunction] || [self doDrawGrid]){
  931.  
  932.       if([self checkMinMax] == 1){   /* check on min/max limits for errors */
  933.     NXBeep(); beepError = 4; return self; }
  934.  
  935.       if(NXDrawingStatus != NX_PRINTING){
  936.     [self drawPlotButton:1];    /* display "Plotting" */
  937.     [canvas display];
  938.     [self drawPlotButton:0];    /* display "Plot" */
  939.       }
  940.     }
  941.     else{ NXBeep(); beepError = 22; return self; }
  942.   }
  943.  
  944.   stateChangeGrid = NO;     /* reset stateChange so old min/max retained*/
  945.   stateChangeFunction = NO;     /* reset stateChange so old min/max retained*/
  946.  
  947.   return self;
  948. }
  949.  
  950.  
  951. // Go through a particular datahunk and find values for datamin.x,
  952. // datamax.x, datamin.y, datamax.y
  953.  
  954.   - findGridMinAndMax
  955. {
  956.   int j;
  957.  
  958.   gridH.gridmin.x = MAXFLOAT;    /* defined in /usr/include/math.h */
  959.   gridH.gridmax.x = -MAXFLOAT;
  960.   gridH.gridmin.y = MAXFLOAT;
  961.   gridH.gridmax.y = -MAXFLOAT;
  962.  
  963.   for (j = 0; j < gridH.jmax*gridH.kmax; j++)  {
  964.      gridH.gridmin.x = MIN(gridH.gridmin.x, gridH.x[j]);
  965.      gridH.gridmax.x = MAX(gridH.gridmax.x, gridH.x[j]);
  966.    }
  967.   for (j = 0; j < gridH.jmax*gridH.kmax; j++)  {
  968.      gridH.gridmin.y = MIN(gridH.gridmin.y, gridH.y[j]);
  969.      gridH.gridmax.y = MAX(gridH.gridmax.y, gridH.y[j]);
  970.    }
  971.   return self;
  972. }
  973.  
  974.   - findFunctionGridMinAndMax
  975. {
  976.   int j;
  977.  
  978.   functionH.gridmin.x = MAXFLOAT;    /* defined in /usr/include/math.h */
  979.   functionH.gridmax.x = -MAXFLOAT;
  980.   functionH.gridmin.y = MAXFLOAT;
  981.   functionH.gridmax.y = -MAXFLOAT;
  982.  
  983.   for (j = 0; j < functionH.jmax*functionH.kmax; j++)  {
  984.      functionH.gridmin.x = MIN(functionH.gridmin.x, functionH.x[j]);
  985.      functionH.gridmax.x = MAX(functionH.gridmax.x, functionH.x[j]);
  986.    }
  987.   for (j = 0; j < functionH.jmax*functionH.kmax; j++)  {
  988.      functionH.gridmin.y = MIN(functionH.gridmin.y, functionH.y[j]);
  989.      functionH.gridmax.y = MAX(functionH.gridmax.y, functionH.y[j]);
  990.    }
  991.   return self;
  992. }
  993.  
  994.   - findFunctionMinAndMax
  995. {
  996.   int j;
  997.  
  998.   functionH.functionmin = MAXFLOAT;    /* defined in /usr/include/math.h */
  999.   functionH.functionmax = -MAXFLOAT;
  1000.  
  1001.  
  1002.   for (j = 0; j < functionH.jmax*functionH.kmax; j++)  {
  1003.      functionH.functionmin = MIN(functionH.functionmin, functionH.f[j]);
  1004.      functionH.functionmax = MAX(functionH.functionmax, functionH.f[j]);
  1005.    }
  1006.   return self;
  1007. }
  1008.  
  1009.  
  1010. // Use the OpenPanel object to get a filename
  1011. - openGrid:sender
  1012. {
  1013. //  char const  *fileTypes[2] = {"xy",0};  
  1014.   char const  *fileTypes[2] = {0,0};  
  1015.   char    fname[1024];
  1016.   
  1017.   [openPanel setTitle:"OPEN GRID FILE"];
  1018.  
  1019.   if ([openPanel runModalForTypes:fileTypes])  {
  1020.     strncpy(fname, [openPanel filename], 1024);
  1021.     [self openGridFile:fname];
  1022.   }
  1023.   return self;
  1024. }
  1025.  
  1026. // Use the OpenPanel object to get a filename
  1027. - openSolution:sender
  1028. {
  1029. //  char const  *fileTypes[2] = {"q",0};  
  1030.   char const  *fileTypes[2] = {0,0};  
  1031.   char    fname[1024];
  1032.  
  1033.   [openPanel setTitle:"OPEN DATA FILE"];
  1034.  
  1035.   if ([openPanel runModalForTypes:fileTypes])  {
  1036.     strncpy(fname, [openPanel filename], 1024);
  1037.     [self openSolnFile:fname];
  1038.   }
  1039.   return self;
  1040. }
  1041.  
  1042. - openGridFile:(char *)dataFile
  1043. {
  1044.     NXStream *dataStream;
  1045.  
  1046.     if ((dataStream = NXMapFile(dataFile, NX_READONLY)) == NULL)  {
  1047.       NXRunAlertPanel("Open", "Cannot open %s", "OK", NULL, NULL, dataFile);
  1048.       return self;
  1049.     }
  1050.  
  1051.     if ([self readGrid:dataStream :dataFile] == 0)  {
  1052.       NXRunAlertPanel("Read", "Couldn't read any data from %s", "OK",
  1053.               NULL, NULL, dataFile);
  1054.       NXCloseMemory(dataStream, NX_FREEBUFFER);
  1055.       return self;
  1056.     }
  1057.     NXCloseMemory(dataStream, NX_FREEBUFFER);
  1058.  
  1059.     [canvasWindow setTitleAsFilename:dataFile];
  1060.     return self;
  1061. }
  1062. - openSolnFile:(char *)dataFile
  1063. {
  1064.     NXStream *dataStream;
  1065.  
  1066.     if ((dataStream = NXMapFile(dataFile, NX_READONLY)) == NULL)  {
  1067.       NXRunAlertPanel("Open", "Cannot open %s", "OK", NULL, NULL, dataFile);
  1068.       return self;
  1069.     }
  1070.  
  1071.     if ([self readSoln:dataStream :dataFile] == 0)  {
  1072.       NXRunAlertPanel("Read", "Couldn't read any data from %s", "OK",
  1073.               NULL, NULL, dataFile);
  1074.       NXCloseMemory(dataStream, NX_FREEBUFFER);
  1075.       return self;
  1076.     }
  1077.     NXCloseMemory(dataStream, NX_FREEBUFFER);
  1078.  
  1079.     [canvasWindow setTitleAsFilename:dataFile];
  1080.     return self;
  1081. }
  1082.  
  1083.  
  1084.  
  1085. /* Allocate enough memory and read the data points */
  1086. - readGrid:(NXStream *)aDataStream :(char *)dataFile
  1087. {
  1088.   int j, numberofpoints, tmpint = 0;
  1089.   char c;
  1090.   BOOL b_2D = [self do2D3D_grid];
  1091.   int filesize,expected_filesize = 0, errorAlert = 0;
  1092.   struct stat filestat;
  1093.  
  1094.   /* set plot button title "Reading" */
  1095.   [plotButton setAltTitle:"Reading"];
  1096.   [plotButton highlight:YES];
  1097.   NXPing();            /* force plotButton redraw */
  1098.   
  1099.   if(![chooseDataType state]){
  1100.     NXRead(aDataStream, &gridhunk.jmax, sizeof(int));
  1101.     NXRead(aDataStream, &gridhunk.kmax, sizeof(int));
  1102.     if(!b_2D){ NXRead(aDataStream, &gridhunk.lmax, sizeof(int)); }
  1103.     else{gridhunk.lmax = 1;}
  1104.   }
  1105.   else{
  1106.     while((tmpint=NXScanf(aDataStream, "%d", &gridhunk.jmax)) == 0){
  1107.       c = (char)NXGetc(aDataStream);    /* throw away the next character */
  1108.     }
  1109.     while((tmpint=NXScanf(aDataStream, "%d", &gridhunk.kmax)) == 0){
  1110.       c = (char)NXGetc(aDataStream);    /* throw away the next character */
  1111.     }
  1112.     if(!b_2D){ 
  1113.       while((tmpint=NXScanf(aDataStream, "%d", &gridhunk.lmax)) == 0){
  1114.     c = (char)NXGetc(aDataStream);    /* throw away the next character */
  1115.       }
  1116.     }
  1117.     else{gridhunk.lmax = 1;}
  1118.   }
  1119.  
  1120.   numberofpoints = gridhunk.jmax*gridhunk.kmax*gridhunk.lmax;
  1121.  
  1122.   if(![chooseDataType state]){
  1123.  
  1124.   /*  check file size */
  1125.     stat(dataFile,&filestat);
  1126.  
  1127.     filesize = filestat.st_size;
  1128.  
  1129.     if(b_2D){
  1130.       
  1131.       expected_filesize = 
  1132.     2*sizeof(int) + 2*sizeof(float)*numberofpoints;
  1133.  
  1134.       if(filesize != expected_filesize){
  1135.     errorAlert = NXRunAlertPanel("Read Grid File", 
  1136.                      "Not a Valid 2D Grid File! %s", 
  1137.                      "Try Again?","Continue?","Abort?", 
  1138.                      dataFile);
  1139.       
  1140.     if(errorAlert  != NX_ALERTALTERNATE){
  1141.       gridhunk.jmax = 0;
  1142.       gridhunk.kmax = 0;
  1143.       gridhunk.lmax = 0;
  1144.     }
  1145.     if(errorAlert  == NX_ALERTOTHER){
  1146.       /* reset plot button */
  1147.       [plotButton setAltTitle:"Plotting"];
  1148.       [plotButton highlight:NO];
  1149.       return self;
  1150.     }
  1151.     if(errorAlert  == NX_ALERTDEFAULT){
  1152.       /* reset plot button */
  1153.       [plotButton setAltTitle:"Plotting"];
  1154.       [plotButton highlight:NO];
  1155.       [self openGrid:self];
  1156.       return self;
  1157.     }
  1158.       }
  1159.     }
  1160.     if(!b_2D){
  1161.  
  1162.       expected_filesize = 
  1163.     3*sizeof(int) + 3*sizeof(float)*numberofpoints;
  1164.  
  1165.       if(filesize != expected_filesize){
  1166.     errorAlert = NXRunAlertPanel("Read Grid File", 
  1167.                      "Not a Valid 3D Grid File! %s ", 
  1168.                      "Try Again?","Continue?","Abort?",
  1169.                      dataFile);
  1170.     if(errorAlert  != NX_ALERTALTERNATE){
  1171.       gridhunk.jmax = 0;
  1172.       gridhunk.kmax = 0;
  1173.       gridhunk.lmax = 0;
  1174.     }
  1175.     if(errorAlert  == NX_ALERTOTHER){
  1176.       /* reset plot button */
  1177.       [plotButton setAltTitle:"Plotting"];
  1178.       [plotButton highlight:NO];
  1179.       return self;
  1180.     }
  1181.     if(errorAlert  == NX_ALERTDEFAULT){
  1182.       /* reset plot button */
  1183.       [plotButton setAltTitle:"Plotting"];
  1184.       [plotButton highlight:NO];
  1185.       [self openGrid:self];
  1186.       return self;
  1187.     }
  1188.       }
  1189.     }
  1190.   }
  1191.  
  1192.   free((void *)gridhunk.x);
  1193.   free((void *)gridhunk.y);
  1194.   gridhunk.x = (NXCoord *)malloc(numberofpoints*sizeof(float));
  1195.   gridhunk.y = (NXCoord *)malloc(numberofpoints*sizeof(float));
  1196.   if(!b_2D){ 
  1197.     free((void *)gridhunk.z);
  1198.     gridhunk.z = (NXCoord *)malloc(numberofpoints*sizeof(float)); 
  1199.   }
  1200.  
  1201.   if(![chooseDataType state]){
  1202.     NXRead(aDataStream, gridhunk.x, numberofpoints*sizeof(float));
  1203.     NXRead(aDataStream, gridhunk.y, numberofpoints*sizeof(float));
  1204.     if(!b_2D){NXRead(aDataStream, gridhunk.z, numberofpoints*sizeof(float)); }
  1205.   }
  1206.   else{
  1207.     for (j=0; j<numberofpoints; j++){
  1208.       while((tmpint=NXScanf(aDataStream, "%f", &gridhunk.x[j])) == 0){
  1209.     c = (char)NXGetc(aDataStream);    /* throw away the next character */
  1210.       }
  1211.     }
  1212.     for (j=0; j<numberofpoints; j++){
  1213.       while((tmpint=NXScanf(aDataStream, "%f", &gridhunk.y[j])) == 0){
  1214.     c = (char)NXGetc(aDataStream);    /* throw away the next character */
  1215.       }
  1216.     }
  1217.     if(!b_2D){
  1218.       for (j=0; j<numberofpoints; j++){
  1219.     while((tmpint=NXScanf(aDataStream, "%f", &gridhunk.z[j])) == 0){
  1220.       c = (char)NXGetc(aDataStream); /* throw away the next character */
  1221.     }
  1222.       }
  1223.     }
  1224.   }
  1225.   /* reset plot button */
  1226.   [plotButton setAltTitle:"Plotting"];
  1227.   [plotButton highlight:NO];
  1228.  
  1229.   /* initialize gridH from gridhunk */
  1230.   /* Initialize as 2D xy plane (jk plane) */
  1231.   gridH.jmax = gridhunk.jmax;
  1232.   gridH.kmax = gridhunk.kmax;
  1233.   free((void *)gridH.x);
  1234.   free((void *)gridH.y);
  1235.   gridH.x = (NXCoord *)malloc(gridH.jmax*gridH.kmax*sizeof(float));
  1236.   gridH.y = (NXCoord *)malloc(gridH.jmax*gridH.kmax*sizeof(float));
  1237.  
  1238.   for (j = 0; j < gridhunk.jmax*gridhunk.kmax; j++){
  1239.     gridH.x[j] = gridhunk.x[j];
  1240.     gridH.y[j] = gridhunk.y[j];
  1241.   }
  1242.       
  1243.   [self findGridMinAndMax];
  1244.  
  1245.  
  1246.   /*  On initial read function-grid min/max set to be same as grid min/max */
  1247.  
  1248.   gridhunk.gridmin.x = gridH.gridmin.x;
  1249.   gridhunk.gridmin.y = gridH.gridmin.y;
  1250.   gridhunk.gridmax.x = gridH.gridmax.x;
  1251.   gridhunk.gridmax.y = gridH.gridmax.y;
  1252.  
  1253.   /*  set min/max forms */
  1254.   [self resetGridSubsets:self];
  1255.   if(!gridIsReadIn){
  1256.     [self resetGridMinMax:self];
  1257.   }
  1258.   stateChangeGrid = NO;
  1259.   gridIsReadIn = YES;
  1260.   return self;
  1261. }
  1262.  
  1263. // Allocate enough memory and read the data points
  1264. - readSoln:(NXStream *)aDataStream :(char *)dataFile
  1265. {
  1266.   float gamma = 1.4;
  1267.   int j, numberofpoints,i,tmpint = 0;
  1268.   char c;
  1269.   BOOL b_2D = [self do2D3D];
  1270.   BOOL aero = [self doAeroDynamics];
  1271.   int filesize,expected_filesize = 0, errorAlert = 0;
  1272.   struct stat filestat;
  1273.   char title[14];
  1274.  
  1275.   /* set plot button title "Reading" */
  1276.   [plotButton setAltTitle:"Reading"];
  1277.   [plotButton highlight:YES];
  1278.   NXPing();            /* force plotButton redraw */
  1279.  
  1280.   number_Of_Functions_Read_In = [numberOfFunctions intValueAt:0];
  1281.  
  1282.   if(!aero){
  1283.  
  1284.     [functionMatrix setTitle:"Function 1" at:0:0];
  1285.     for(i=1; i< number_Of_Functions_Read_In; i++){
  1286.       sprintf(title,"Function %d",i+1);
  1287.       [functionMatrix setTitle:title at:i:0];
  1288.     }
  1289.     for(i=number_Of_Functions_Read_In; i<12; i++){
  1290.       [functionMatrix setTitle:"Inactive" at:i:0];
  1291.     }      
  1292.     [functionMatrix display];
  1293.   }
  1294.  
  1295.   if(aero){
  1296.     if(b_2D && number_Of_Functions_Read_In !=4){
  1297.       NXBeep();    beepError = 27;        /* audible alert */
  1298.       errorAlert = NXRunAlertPanel("Possible Read Data Error", 
  1299.                    "In 2D AeroDynamic Mode usually \n number of functions = 4 : you have %d", 
  1300.                    "Reset to 4","Continue?",NULL,
  1301.                    number_Of_Functions_Read_In);
  1302.       if(errorAlert  == NX_ALERTDEFAULT){
  1303.     number_Of_Functions_Read_In = 4;
  1304.     [numberOfFunctions setIntValue:4 at:0];
  1305.       }
  1306.  
  1307.     }
  1308.     if(!b_2D && number_Of_Functions_Read_In !=5){
  1309.       NXBeep();    beepError = 27;        /* audible alert */
  1310.       errorAlert = NXRunAlertPanel("Possible Read Data Error", 
  1311.                    "In 3D AeroDynamic Mode usually \n number of functions = 5 : you have %d", 
  1312.                    "Reset to 5","Continue?",NULL,
  1313.                    number_Of_Functions_Read_In);
  1314.       if(errorAlert  == NX_ALERTDEFAULT){
  1315.     number_Of_Functions_Read_In = 5;
  1316.     [numberOfFunctions setIntValue:5 at:0];
  1317.       }
  1318.  
  1319.     }
  1320.  
  1321.     if((b_2D && number_Of_Functions_Read_In !=4)||
  1322.        (!b_2D && number_Of_Functions_Read_In !=5)){
  1323.       [functionMatrix setTitle:"Function 1" at:0:0];
  1324.       for(i=1; i< number_Of_Functions_Read_In; i++){
  1325.     sprintf(title,"Function %d",i+1);
  1326.     [functionMatrix setTitle:title at:i:0];
  1327.       }
  1328.       for(i=number_Of_Functions_Read_In; i<12; i++){
  1329.     [functionMatrix setTitle:"Inactive" at:i:0];
  1330.       }      
  1331.     }
  1332.     else{
  1333.       [functionMatrix setTitle:"Q1: Density"    at:0:0];
  1334.       [functionMatrix setTitle:"Q2: U-Momentum" at:1:0];
  1335.       [functionMatrix setTitle:"Q3: V-Momentum" at:2:0];
  1336.       if(!b_2D)[functionMatrix setTitle:"Q4: W-Momentum" at:3:0];
  1337.       if(b_2D)[functionMatrix setTitle:"Inactive" at:3:0];
  1338.       if(!b_2D)[functionMatrix setTitle:"Q5: Energy"     at:4:0];
  1339.       if(b_2D)[functionMatrix setTitle:"Q4: Energy"     at:4:0];
  1340.       [functionMatrix setTitle:"Mach Number"    at:5:0];
  1341.       [functionMatrix setTitle:"Pressure"       at:6:0];
  1342.       [functionMatrix setTitle:"Cp"             at:7:0];
  1343.       [functionMatrix setTitle:"U-Velocity"     at:8:0];
  1344.       [functionMatrix setTitle:"V-Velocity"     at:9:0];
  1345.       if(!b_2D)[functionMatrix setTitle:"W-Velocity"     at:10:0];
  1346.       if(b_2D)[functionMatrix setTitle:"Inactive"     at:10:0];
  1347.     }
  1348.     [functionMatrix display];
  1349.  
  1350.   }
  1351.  
  1352.   if(![chooseDataType state]){
  1353.     NXRead(aDataStream, &solnhunk.jmax, sizeof(int));
  1354.     NXRead(aDataStream, &solnhunk.kmax, sizeof(int));
  1355.     if(!b_2D){ NXRead(aDataStream, &solnhunk.lmax, sizeof(int)); }
  1356.     else{solnhunk.lmax = 1;}
  1357.   }
  1358.   else{
  1359.     while((tmpint=NXScanf(aDataStream, "%d", &solnhunk.jmax)) == 0){
  1360.       c = (char)NXGetc(aDataStream);    /* throw away the next character */
  1361.     }
  1362.     while((tmpint=NXScanf(aDataStream, "%d", &solnhunk.kmax)) == 0){
  1363.       c = (char)NXGetc(aDataStream);    /* throw away the next character */
  1364.     }
  1365.     if(!b_2D){ 
  1366.       while((tmpint=NXScanf(aDataStream, "%d", &solnhunk.lmax)) == 0){
  1367.     c = (char)NXGetc(aDataStream);    /* throw away the next character */
  1368.       }
  1369.     }
  1370.     else{solnhunk.lmax = 1;}
  1371.   }
  1372.  
  1373.   numberofpoints = solnhunk.jmax*solnhunk.kmax*solnhunk.lmax;
  1374.  
  1375.  
  1376.   if(![chooseDataType state]){
  1377.     /*  check file size */
  1378.     stat(dataFile,&filestat);
  1379.     
  1380.     filesize = filestat.st_size;
  1381.     
  1382.     if(b_2D){
  1383.       
  1384.       if(!aero)expected_filesize = 
  1385.     2*sizeof(int) + number_Of_Functions_Read_In*sizeof(float)*
  1386.       numberofpoints;
  1387.       
  1388.       if(aero)expected_filesize = 
  1389.     2*sizeof(int) + 4*sizeof(float) + 
  1390.       number_Of_Functions_Read_In*sizeof(float)*numberofpoints;
  1391.       
  1392.       if(filesize != expected_filesize){
  1393.     errorAlert = NXRunAlertPanel("Read Grid File Error", 
  1394.                      "Not a Valid 2D Data File! %s", 
  1395.                      "Try Again?","Continue","Abort?",
  1396.                      dataFile);
  1397.     if(errorAlert  != NX_ALERTALTERNATE){
  1398.       solnhunk.jmax = 0;
  1399.       solnhunk.kmax = 0;
  1400.       solnhunk.lmax = 0;
  1401.     }
  1402.     if(errorAlert  == NX_ALERTOTHER){
  1403.       /* reset plot button */
  1404.       [plotButton setAltTitle:"Plotting"];
  1405.       [plotButton highlight:NO];
  1406.       return self;
  1407.     }
  1408.     if(errorAlert  == NX_ALERTDEFAULT){
  1409.       /* reset plot button */
  1410.       [plotButton setAltTitle:"Plotting"];
  1411.       [plotButton highlight:NO];
  1412.       [self openSolution:self];
  1413.       return self;
  1414.     }
  1415.       }
  1416.     }
  1417.     
  1418.     if(!b_2D){
  1419.       if(!aero)expected_filesize = 
  1420.     3*sizeof(int) + number_Of_Functions_Read_In*sizeof(float)*
  1421.       numberofpoints;
  1422.       
  1423.       if(aero)expected_filesize = 
  1424.     3*sizeof(int) + 4*sizeof(float) + 
  1425.       number_Of_Functions_Read_In*sizeof(float)*numberofpoints;
  1426.       
  1427.       if(filesize != expected_filesize){
  1428.     errorAlert = NXRunAlertPanel("Read Data File Error", 
  1429.                      "Not a Valid 3D Data File! %s", 
  1430.                      "Try Again?","Continue?","Abort?",
  1431.                      dataFile);
  1432.     if(errorAlert  != NX_ALERTALTERNATE){
  1433.       solnhunk.jmax = 0;
  1434.       solnhunk.kmax = 0;
  1435.       solnhunk.lmax = 0;
  1436.     }
  1437.     if(errorAlert  == NX_ALERTOTHER){
  1438.       /* reset plot button */
  1439.       [plotButton setAltTitle:"Plotting"];
  1440.       [plotButton highlight:NO];
  1441.       return self;
  1442.     }
  1443.     if(errorAlert  == NX_ALERTDEFAULT){
  1444.       /* reset plot button */
  1445.       [plotButton setAltTitle:"Plotting"];
  1446.       [plotButton highlight:NO];
  1447.       [self openSolution:self];
  1448.       return self;
  1449.     }
  1450.       }
  1451.     }
  1452.   }
  1453.  
  1454.   /*  checkpoint on data grid sizes against grid file*/
  1455.   if( (gridhunk.jmax != solnhunk.jmax) || (gridhunk.kmax != solnhunk.kmax)
  1456.      || (gridhunk.lmax != solnhunk.lmax) ){
  1457.  
  1458.     if(gridhunk.jmax == 0 ){
  1459.       errorAlert = NXRunAlertPanel("Read Data FileError", 
  1460.                    "Need to Read In A Grid First", 
  1461.                    "Try Again?","Continue?", "Abort?");
  1462.     }
  1463.     else{
  1464.       if(b_2D)errorAlert = 
  1465.     NXRunAlertPanel("Read Data FileError", 
  1466.             "Inconsistent Dimensions, you had %d %d\n File %s", 
  1467.             "Try Again?","Continue?", "Abort?",
  1468.             solnhunk.jmax,solnhunk.kmax,dataFile);
  1469.       if(!b_2D)errorAlert = 
  1470.     NXRunAlertPanel("Read Data FileError", 
  1471.             "Inconsistent Dimensions, you had %d %d %d\n File %s", 
  1472.             "Try Again?","Continue?", "Abort?",
  1473.             solnhunk.jmax,solnhunk.kmax,solnhunk.lmax,dataFile);
  1474.     }
  1475.  
  1476.     if(errorAlert  != NX_ALERTALTERNATE){
  1477.       solnhunk.jmax = 0;
  1478.       solnhunk.kmax = 0;
  1479.       solnhunk.lmax = 0;
  1480.     }
  1481.     if(errorAlert  == NX_ALERTOTHER){
  1482.       /* reset plot button */
  1483.       [plotButton setAltTitle:"Plotting"];
  1484.       [plotButton highlight:NO];
  1485.       return self;
  1486.     }
  1487.     if(errorAlert  == NX_ALERTDEFAULT){
  1488.       /* reset plot button */
  1489.       [plotButton setAltTitle:"Plotting"];
  1490.       [plotButton highlight:NO];
  1491.       [self openSolution:self];
  1492.       return self;
  1493.     }
  1494.   }
  1495.  
  1496.   if(![chooseDataType state]){
  1497.     if(aero){
  1498.       NXRead(aDataStream, &solnhunk.fsmach, sizeof(float));
  1499.       NXRead(aDataStream, &solnhunk.alpha, sizeof(float));
  1500.       NXRead(aDataStream, &solnhunk.re, sizeof(float));
  1501.       NXRead(aDataStream, &solnhunk.time, sizeof(float));
  1502.     }
  1503.   }
  1504.   else{
  1505.     if(aero){
  1506.       while((tmpint=NXScanf(aDataStream, "%f", &solnhunk.fsmach)) == 0){
  1507.     c = (char)NXGetc(aDataStream);    /* throw away the next character */
  1508.       }
  1509.       while((tmpint=NXScanf(aDataStream, "%f", &solnhunk.alpha)) == 0){
  1510.     c = (char)NXGetc(aDataStream);    /* throw away the next character */
  1511.       }
  1512.       while((tmpint=NXScanf(aDataStream, "%f", &solnhunk.re)) == 0){
  1513.     c = (char)NXGetc(aDataStream);    /* throw away the next character */
  1514.       }
  1515.       while((tmpint=NXScanf(aDataStream, "%f", &solnhunk.time)) == 0){
  1516.     c = (char)NXGetc(aDataStream);    /* throw away the next character */
  1517.       }
  1518.     }
  1519.   }
  1520.   
  1521.   free((void *)solnhunk.functions);
  1522.   solnhunk.functions    = 
  1523.     (NXCoord *)malloc(number_Of_Functions_Read_In*
  1524.               numberofpoints*sizeof(float));
  1525.  
  1526.   if(aero){
  1527.     free((void *)solnhunk.pressure);
  1528.     free((void *)solnhunk.mach_number);
  1529.     solnhunk.pressure    = (NXCoord *)malloc(numberofpoints*sizeof(float));
  1530.     solnhunk.mach_number = (NXCoord *)malloc(numberofpoints*sizeof(float));
  1531.   }
  1532.  
  1533.   if(![chooseDataType state]){
  1534.     NXRead(aDataStream, solnhunk.functions,  
  1535.        number_Of_Functions_Read_In*numberofpoints*sizeof(float));
  1536.   }
  1537.   else{
  1538.     for (j=0; j<numberofpoints*number_Of_Functions_Read_In; j++){
  1539.       while((tmpint=NXScanf(aDataStream, "%f", &solnhunk.functions[j])) == 0){
  1540.     c = (char)NXGetc(aDataStream);    /* throw away the next character */
  1541.       }
  1542.     }
  1543.   }
  1544.  
  1545.   /*compute pressure and mach number here to speed up plotting */
  1546.   if(!b_2D && aero){
  1547.     for(i=0; i < numberofpoints; i++){
  1548.       
  1549.       solnhunk.mach_number[i] = 
  1550.      (solnhunk.functions[i+numberofpoints]*
  1551.       solnhunk.functions[i+numberofpoints] + 
  1552.       solnhunk.functions[i+2*numberofpoints]*
  1553.       solnhunk.functions[i+2*numberofpoints] + 
  1554.       solnhunk.functions[i+3*numberofpoints]*
  1555.       solnhunk.functions[i+3*numberofpoints]); 
  1556.  
  1557.  
  1558.       solnhunk.pressure[i] = (gamma-1.0)*
  1559.     (solnhunk.functions[i+4*numberofpoints] - 
  1560.      0.5* solnhunk.mach_number[i]/solnhunk.functions[i]);
  1561.  
  1562.       solnhunk.mach_number[i] = 
  1563.     sqrt(solnhunk.mach_number[i] / 
  1564.          (gamma * solnhunk.functions[i] * solnhunk.pressure[i]));
  1565.  
  1566.     }
  1567.   }
  1568.  
  1569.   if(b_2D && aero){
  1570.     for(i=0; i < numberofpoints; i++){
  1571.  
  1572.       solnhunk.mach_number[i] = 
  1573.      (solnhunk.functions[i+numberofpoints]*
  1574.       solnhunk.functions[i+numberofpoints] + 
  1575.       solnhunk.functions[i+2*numberofpoints]*
  1576.       solnhunk.functions[i+2*numberofpoints]);
  1577.  
  1578.  
  1579.       solnhunk.pressure[i] = (gamma-1.0)*
  1580.     (solnhunk.functions[i+3*numberofpoints] - 
  1581.      0.5* solnhunk.mach_number[i]/solnhunk.functions[i]);
  1582.  
  1583.       solnhunk.mach_number[i] = 
  1584.     sqrt(solnhunk.mach_number[i] / 
  1585.          (gamma * solnhunk.functions[i] * solnhunk.pressure[i]));
  1586.  
  1587.     }
  1588.   }
  1589.  
  1590.  
  1591.     /* reset plot button */
  1592.   [plotButton setAltTitle:"Plotting"];
  1593.   [plotButton highlight:NO];
  1594.  
  1595.   /* initialize functionH from gridhunk */
  1596.   /* Initialize as 2D xy plane (jk plane) */
  1597.   functionH.jmax = solnhunk.jmax;
  1598.   functionH.kmax = solnhunk.kmax;
  1599.  
  1600.   free((void *)functionH.x);  functionH.x = 
  1601.     (NXCoord *)malloc(functionH.jmax*functionH.kmax*sizeof(float));
  1602.   free((void *)functionH.y);  functionH.y = 
  1603.     (NXCoord *)malloc(functionH.jmax*functionH.kmax*sizeof(float));
  1604.   free((void *)functionH.f);  functionH.f = 
  1605.     (NXCoord *)malloc(functionH.jmax*functionH.kmax*sizeof(float));
  1606.  
  1607.   for (j=0; j < solnhunk.jmax*solnhunk.kmax; j++){
  1608.     functionH.x[j] = gridhunk.x[j];
  1609.     functionH.y[j] = gridhunk.y[j];
  1610.     functionH.f[j] = solnhunk.functions[j];
  1611.   }
  1612.  
  1613.   if(!solutionIsReadIn){
  1614.     [self resetFunctionSubsets:self];
  1615.     [self resetLineSubsets:self];
  1616.   }
  1617.  
  1618.   [self findFunctionGridMinAndMax];
  1619.   [self findFunctionMinAndMax];
  1620.   if(!solutionIsReadIn){
  1621.     [self resetFunctionGridMinMax:self];
  1622.     [self resetFunctionMinMax:self];
  1623.   }
  1624.   stateChangeFunction = NO;
  1625.   solutionIsReadIn = YES;
  1626.   return self;
  1627. }
  1628.  
  1629.  
  1630.  
  1631. - loadGrid:sender
  1632. {
  1633.   int  j, k, l, i, ii;
  1634.   int  jdim = gridhunk.jmax;
  1635.   int  kdim = gridhunk.kmax;
  1636.   int  jmax = gridhunk.jmax;
  1637.   int  kmax = gridhunk.kmax;
  1638.   int j_0,j_i,j_m,k_0,k_i,k_m,l_0,l_i,l_m;
  1639.   int planeChoice = [chooseGridPlane selectedRow];
  1640.   int viewChoice = 
  1641.     [viewingTransformations selectedRow] + 
  1642.       4*[viewingTransformations selectedCol];
  1643.   BOOL b_2D_grid = [self do2D3D_grid];
  1644.   BOOL b_2D = [self do2D3D];
  1645.  
  1646.   if(!b_2D && b_2D_grid)[self eQuateSubsets:self];
  1647.  
  1648.   /* failsafe for 2d/3d */
  1649.   if(b_2D_grid){
  1650.     if(viewChoice != 0 && viewChoice != 4 && viewChoice != 3){
  1651.       NXBeep(); beepError = 11;
  1652.       viewChoice = 0;
  1653.       [viewingTransformations selectCellAt:viewChoice:0];
  1654.     }
  1655.     if(planeChoice != 2){
  1656.       NXBeep(); beepError = 12;
  1657.       planeChoice = 2;
  1658.       [chooseGridPlane selectCellAt:planeChoice:0];
  1659.     }
  1660.   }
  1661.  
  1662.   
  1663. /* shift indices down 1  */
  1664.   j_0 = [jGridMin intValueAt:0] - 1;
  1665.   j_i = [jGridInc intValueAt:0];
  1666.   j_m = [jGridMax intValueAt:0] - 1;
  1667.  
  1668.   k_0 = [kGridMin intValueAt:0] - 1;
  1669.   k_i = [kGridInc intValueAt:0];
  1670.   k_m = [kGridMax intValueAt:0] - 1;
  1671.  
  1672.   l_0 = [lGridMin intValueAt:0] - 1;
  1673.   l_i = [lGridInc intValueAt:0];
  1674.   l_m = [lGridMax intValueAt:0] - 1;
  1675.   
  1676.  
  1677.   /* failsafe, j or k can never be <=0 || >= max*/
  1678.   if(j_i <= 0 || j_i > gridhunk.jmax){
  1679.     NXBeep();  beepError = 20;
  1680.     j_i = 1;
  1681.     [jGridInc setIntValue:j_i at:0];
  1682.   }
  1683.   if(j_0 < 0 || j_0 > gridhunk.jmax-1){
  1684.     NXBeep();  beepError = 20;
  1685.     j_0 = 0;
  1686.     [jGridMin setIntValue:j_0+1 at:0];
  1687.   }
  1688.   if(j_m < 0 || j_m > gridhunk.jmax-1){
  1689.     NXBeep();  beepError = 20;
  1690.     j_m = gridhunk.jmax-1;
  1691.     [jGridMax setIntValue:j_m+1 at:0];
  1692.   }
  1693.   if(j_m < j_0 && planeChoice != 0){
  1694.     NXBeep();  beepError = 20;
  1695.     j_0 = 0;
  1696.     [jGridMin setIntValue:j_0+1 at:0];
  1697.     j_m = gridhunk.jmax-1;
  1698.     [jGridMax setIntValue:j_m+1 at:0];
  1699.   }
  1700.   
  1701.   if(k_i <= 0 || k_i > gridhunk.kmax){
  1702.     NXBeep();  beepError = 20;
  1703.     k_i = 1;
  1704.     [kGridInc setIntValue:k_i at:0];
  1705.   }
  1706.   if(k_0 < 0 || k_0 > gridhunk.kmax-1){
  1707.     NXBeep();  beepError = 20;
  1708.     k_0 = 0;
  1709.     [kGridMin setIntValue:k_0+1 at:0];
  1710.   }
  1711.   if(k_m < 0 || k_m > gridhunk.kmax-1){
  1712.     NXBeep();  beepError = 20;
  1713.     k_m = gridhunk.kmax-1;
  1714.     [kGridMax setIntValue:k_m+1 at:0];
  1715.   }
  1716.   if(k_m < k_0 && planeChoice != 1){
  1717.     NXBeep();  beepError = 20;
  1718.     k_0 = 0;
  1719.     [kGridMin setIntValue:k_0+1 at:0];
  1720.     k_m = gridhunk.kmax-1;
  1721.     [kGridMax setIntValue:k_m+1 at:0];
  1722.   }
  1723.   
  1724.   if(l_i <= 0 || l_i > gridhunk.lmax){
  1725.     NXBeep();  beepError = 20;
  1726.     l_i = 1;
  1727.     [lGridInc setIntValue:l_i at:0];
  1728.   }
  1729.   if(l_0 < 0 || l_0 > gridhunk.lmax-1){
  1730.     NXBeep();  beepError = 20;
  1731.     l_0 = 0;
  1732.     [lGridMin setIntValue:l_0+1 at:0];
  1733.   }
  1734.   if(l_m < 0 || l_m > gridhunk.lmax-1){
  1735.     NXBeep();  beepError = 20;
  1736.     l_m = gridhunk.lmax-1;
  1737.     [lGridMax setIntValue:l_m+1 at:0];
  1738.   }
  1739.   if(l_m < l_0 && planeChoice != 2){
  1740.     NXBeep();  beepError = 20;
  1741.     l_0 = 0;
  1742.     [lGridMin setIntValue:l_0+1 at:0];
  1743.     l_m = gridhunk.lmax-1;
  1744.     [lGridMax setIntValue:l_m+1 at:0];
  1745.   }
  1746.  
  1747.  
  1748.   switch(planeChoice){
  1749.  
  1750.   case 0:
  1751.     jdim = (k_m - k_0)/k_i + 1;
  1752.     kdim = (l_m - l_0)/l_i + 1;
  1753.     j_m = j_0;
  1754.     [jGridMax setIntValue:j_m+1 at:0];
  1755.     j_i = 1;
  1756.     [jGridInc setIntValue:j_i at:0];
  1757.     break;
  1758.   case 1:
  1759.     jdim = (j_m - j_0)/j_i + 1;
  1760.     kdim = (l_m - l_0)/l_i + 1;
  1761.     k_m = k_0;
  1762.     [kGridMax setIntValue:k_m+1 at:0];
  1763.     k_i = 1;
  1764.     [kGridInc setIntValue:k_i at:0];
  1765.     break;
  1766.   case 2:
  1767.     jdim = (j_m - j_0)/j_i + 1;
  1768.     kdim = (k_m - k_0)/k_i + 1;
  1769.     l_m = l_0;
  1770.     [lGridMax setIntValue:l_m+1 at:0];
  1771.     l_i = 1;
  1772.     [lGridInc setIntValue:l_i at:0];
  1773.     break;
  1774.   }
  1775.  
  1776.   free((void *)gridH.x);
  1777.   free((void *)gridH.y);
  1778.   
  1779.   gridH.jmax = jdim;
  1780.   gridH.kmax = kdim;
  1781.   gridH.x = (NXCoord *)malloc(jdim*kdim*sizeof(float));
  1782.   gridH.y = (NXCoord *)malloc(jdim*kdim*sizeof(float));
  1783.   
  1784.   switch(viewChoice){
  1785.     
  1786.   case 0:
  1787.     ii = 0;
  1788.     for (l = l_0; l <= l_m; l= l + l_i){
  1789.       for (k = k_0; k <= k_m; k= k + k_i){
  1790.     for (j = j_0; j <= j_m; j = j + j_i){
  1791.       i = l*jmax*kmax + k*jmax + j;
  1792.       gridH.x[ii] = gridhunk.x[i];
  1793.       gridH.y[ii] = gridhunk.y[i];
  1794.       ii = ii+1;
  1795.     }
  1796.       }
  1797.     }
  1798.     break;
  1799.     
  1800.   case 1:
  1801.     
  1802.     ii = 0;
  1803.     for (l = l_0; l <= l_m; l= l + l_i){
  1804.       for (k = k_0; k <= k_m; k= k + k_i){
  1805.     for (j = j_0; j <= j_m; j = j + j_i){
  1806.       i = l*jmax*kmax + k*jmax + j;
  1807.       gridH.x[ii] = gridhunk.x[i];
  1808.       gridH.y[ii] = gridhunk.z[i];
  1809.       ii = ii+1;
  1810.     }
  1811.       }
  1812.     }
  1813.     break;
  1814.     
  1815.   case 2:
  1816.     
  1817.     ii = 0;
  1818.     for (l = l_0; l <= l_m; l= l + l_i){
  1819.       for (k = k_0; k <= k_m; k= k + k_i){
  1820.     for (j = j_0; j <= j_m; j = j + j_i){
  1821.       i = l*jmax*kmax + k*jmax + j;
  1822.       gridH.x[ii] = gridhunk.y[i];
  1823.       gridH.y[ii] = gridhunk.z[i];
  1824.       ii = ii+1;
  1825.     }
  1826.       }
  1827.     }
  1828.     break;
  1829.     
  1830.   case 3:
  1831.     
  1832.     ii = 0;
  1833.     for (l = l_0; l <= l_m; l= l + l_i){
  1834.       for (k = k_0; k <= k_m; k= k + k_i){
  1835.     for (j = j_0; j <= j_m; j = j + j_i){
  1836.       switch(planeChoice){
  1837.       case 2:
  1838.         gridH.x[ii] = (float)j+1;
  1839.         gridH.y[ii] = (float)k+1;
  1840.         break;
  1841.       case 0:
  1842.         gridH.x[ii] = (float)k+1;
  1843.         gridH.y[ii] = (float)l+1;
  1844.         break;
  1845.       case 1:
  1846.         gridH.x[ii] = (float)j+1;
  1847.         gridH.y[ii] = (float)l+1;
  1848.         break;
  1849.       }
  1850.       ii = ii+1;
  1851.     }
  1852.       }
  1853.     }
  1854.     break;
  1855.     
  1856.   case 4:
  1857.     ii = 0;
  1858.     for (l = l_0; l <= l_m; l= l + l_i){
  1859.       for (k = k_0; k <= k_m; k= k + k_i){
  1860.     for (j = j_0; j <= j_m; j = j + j_i){
  1861.       i = l*jmax*kmax + k*jmax + j;
  1862.       gridH.x[ii] = gridhunk.y[i];
  1863.       gridH.y[ii] = gridhunk.x[i];
  1864.       ii = ii+1;
  1865.     }
  1866.       }
  1867.     }
  1868.     break;
  1869.     
  1870.   case 5:
  1871.     
  1872.     ii = 0;
  1873.     for (l = l_0; l <= l_m; l= l + l_i){
  1874.       for (k = k_0; k <= k_m; k= k + k_i){
  1875.     for (j = j_0; j <= j_m; j = j + j_i){
  1876.       i = l*jmax*kmax + k*jmax + j;
  1877.       gridH.x[ii] = gridhunk.z[i];
  1878.       gridH.y[ii] = gridhunk.x[i];
  1879.       ii = ii+1;
  1880.     }
  1881.       }
  1882.     }
  1883.     break;
  1884.     
  1885.   case 6:
  1886.     
  1887.     ii = 0;
  1888.     for (l = l_0; l <= l_m; l= l + l_i){
  1889.       for (k = k_0; k <= k_m; k= k + k_i){
  1890.     for (j = j_0; j <= j_m; j = j + j_i){
  1891.       i = l*jmax*kmax + k*jmax + j;
  1892.       gridH.x[ii] = gridhunk.z[i];
  1893.       gridH.y[ii] = gridhunk.y[i];
  1894.       ii = ii+1;
  1895.     }
  1896.       }
  1897.     }
  1898.     break;
  1899.   }
  1900.   
  1901.   [self findGridMinAndMax];
  1902. ///////  if(stateChangeGrid && !stateChangeFunction)[self resetGridMinMax:self];
  1903.   
  1904.   return self;
  1905. }
  1906.  
  1907. - loadFunction:sender
  1908. {
  1909.   int  j, k, l, i, ii;
  1910.   int  jdim = solnhunk.jmax;
  1911.   int  kdim = solnhunk.kmax;
  1912.   int  jmax = solnhunk.jmax;
  1913.   int  kmax = solnhunk.kmax;
  1914.   int j_0,j_i,j_m,k_0,k_i,k_m,l_0,l_i,l_m;
  1915.   int planeChoice = [chooseFunctionPlane selectedRow];
  1916.   int viewChoice = 
  1917.     [viewingTransformations selectedRow] + 
  1918.       4*[viewingTransformations selectedCol];
  1919.   int functionChoice = [functionMatrix selectedRow];
  1920.   BOOL b_2D = [self do2D3D];
  1921.   BOOL aero = [self doAeroDynamics];
  1922.   float gamma = 1.4;
  1923.   int numberofpoints;
  1924.   
  1925.   numberofpoints = solnhunk.jmax*solnhunk.kmax*solnhunk.lmax;
  1926.  
  1927.   /* failsafes for 2d/3d multiple vrs single functions*/
  1928.  
  1929.   if(!aero && functionChoice+1 > number_Of_Functions_Read_In ){
  1930.     NXBeep();    beepError = 13;        /* audible alert */
  1931.     functionChoice = 0;
  1932.     [functionMatrix selectCellAt:functionChoice:0];
  1933.   }
  1934.  
  1935.   if(aero){
  1936.     if((number_Of_Functions_Read_In != 4 && b_2D) ||
  1937.        (number_Of_Functions_Read_In != 5 && !b_2D)){
  1938.       if(functionChoice+1 > number_Of_Functions_Read_In ){
  1939.     NXBeep();    beepError = 13;        /* audible alert */
  1940.     functionChoice = 0;
  1941.     [functionMatrix selectCellAt:functionChoice:0];
  1942.       }
  1943.     }
  1944.   }
  1945.  
  1946.   if(b_2D){
  1947.     if((functionChoice == 3 || functionChoice == 10 )
  1948.        && (aero && number_Of_Functions_Read_In == 4)){
  1949.       NXBeep();    beepError = 14;    /* audible alert */
  1950.       functionChoice = 0;
  1951.       [functionMatrix selectCellAt:functionChoice:0];
  1952.     }
  1953.     if(viewChoice != 0 && viewChoice != 4 && viewChoice != 3){
  1954.       NXBeep();  beepError = 15;
  1955.       viewChoice = 0;
  1956.       [viewingTransformations selectCellAt:viewChoice:0];
  1957.     }
  1958.     if(planeChoice != 2){
  1959.       NXBeep(); beepError = 16;
  1960.       planeChoice = 2;
  1961.       [chooseFunctionPlane selectCellAt:planeChoice:0];
  1962.     }
  1963.   }
  1964.  
  1965.  
  1966.   /* shift indices down 1  */
  1967.   j_0 = [jFunctionMin intValueAt:0] - 1;
  1968.   j_i = [jFunctionInc intValueAt:0];
  1969.   j_m = [jFunctionMax intValueAt:0] - 1;
  1970.  
  1971.   k_0 = [kFunctionMin intValueAt:0] - 1;
  1972.   k_i = [kFunctionInc intValueAt:0];
  1973.   k_m = [kFunctionMax intValueAt:0] - 1;
  1974.  
  1975.   l_0 = [lFunctionMin intValueAt:0] - 1;
  1976.   l_i = [lFunctionInc intValueAt:0];
  1977.   l_m = [lFunctionMax intValueAt:0] - 1;
  1978.   
  1979.  
  1980.   /* failsafe, j or k can never be <=0 || >= max*/
  1981.       if(j_i <= 0 || j_i > solnhunk.jmax){
  1982.     NXBeep();  beepError = 21;
  1983.     j_i = 1;
  1984.     [jFunctionInc setIntValue:j_i at:0];
  1985.       }
  1986.       if(j_0 < 0 || j_0 > solnhunk.jmax-1){
  1987.     NXBeep();  beepError = 21;
  1988.     j_0 = 0;
  1989.     [jFunctionMin setIntValue:j_0+1 at:0];
  1990.       }
  1991.       if(j_m < 0 || j_m > solnhunk.jmax-1){
  1992.     NXBeep();  beepError = 21;
  1993.     j_m = solnhunk.jmax-1;
  1994.     [jFunctionMax setIntValue:j_m+1 at:0];
  1995.       }
  1996.       if(j_m < j_0 && planeChoice != 0){
  1997.     NXBeep();  beepError = 21;
  1998.     j_0 = 0;
  1999.     [jFunctionMin setIntValue:j_0+1 at:0];
  2000.     j_m = solnhunk.jmax-1;
  2001.     [jFunctionMax setIntValue:j_m+1 at:0];
  2002.       }
  2003.  
  2004.       if(k_i <= 0 || k_i > solnhunk.kmax){
  2005.     NXBeep();  beepError = 21;
  2006.     k_i = 1;
  2007.     [kFunctionInc setIntValue:k_i at:0];
  2008.       }
  2009.       if(k_0 < 0 || k_0 > solnhunk.kmax-1){
  2010.     NXBeep();  beepError = 21;
  2011.     k_0 = 0;
  2012.     [kFunctionMin setIntValue:k_0+1 at:0];
  2013.       }
  2014.       if(k_m < 0 || k_m > solnhunk.kmax-1){
  2015.     NXBeep();  beepError = 21;
  2016.     k_m = solnhunk.kmax-1;
  2017.     [kFunctionMax setIntValue:k_m+1 at:0];
  2018.       }
  2019.       if(k_m < k_0 && planeChoice != 1){
  2020.     NXBeep();  beepError = 21;
  2021.     k_0 = 0;
  2022.     [kFunctionMin setIntValue:k_0+1 at:0];
  2023.     k_m = solnhunk.kmax-1;
  2024.     [kFunctionMax setIntValue:k_m+1 at:0];
  2025.       }
  2026.  
  2027.       if(l_i <= 0 || l_i > solnhunk.lmax){
  2028.     NXBeep();  beepError = 21;
  2029.     l_i = 1;
  2030.     [lFunctionInc setIntValue:l_i at:0];
  2031.       }
  2032.       if(l_0 < 0 || l_0 > solnhunk.lmax-1){
  2033.     NXBeep();  beepError = 21;
  2034.     l_0 = 0;
  2035.     [lFunctionMin setIntValue:l_0+1 at:0];
  2036.       }
  2037.       if(l_m < 0 || l_m > solnhunk.lmax-1){
  2038.     NXBeep();  beepError = 21;
  2039.     l_m = solnhunk.lmax-1;
  2040.     [lFunctionMax setIntValue:l_m+1 at:0];
  2041.       }
  2042.       if(l_m < l_0 && planeChoice != 2){
  2043.     NXBeep();  beepError = 21;
  2044.     l_0 = 0;
  2045.     [lFunctionMin setIntValue:l_0+1 at:0];
  2046.     l_m = solnhunk.lmax-1;
  2047.     [lFunctionMax setIntValue:l_m+1 at:0];
  2048.       }
  2049.   
  2050.   switch(planeChoice){
  2051.     
  2052.   case 0:
  2053.     jdim = (k_m - k_0)/k_i + 1;
  2054.     kdim = (l_m - l_0)/l_i + 1;
  2055.     j_m = j_0;
  2056.     [jFunctionMax setIntValue:j_m+1 at:0];
  2057.     j_i = 1;
  2058.     [jFunctionInc setIntValue:j_i at:0];
  2059.     break;
  2060.   case 1:
  2061.     jdim = (j_m - j_0)/j_i + 1;
  2062.     kdim = (l_m - l_0)/l_i + 1;
  2063.     k_m = k_0;
  2064.     [kFunctionMax setIntValue:k_m+1 at:0];
  2065.     k_i = 1;
  2066.     [kFunctionInc setIntValue:k_i at:0];
  2067.     break;
  2068.   case 2:
  2069.     jdim = (j_m - j_0)/j_i + 1;
  2070.     kdim = (k_m - k_0)/k_i + 1;
  2071.     l_m = l_0;
  2072.     [lFunctionMax setIntValue:l_m+1 at:0];
  2073.     l_i = 1;
  2074.     [lFunctionInc setIntValue:l_i at:0];
  2075.     break;
  2076.   }
  2077.  
  2078.   free((void *)functionH.f);
  2079.  
  2080.   functionH.jmax = jdim;
  2081.   functionH.kmax = kdim;
  2082.   functionH.f =  (NXCoord *)malloc(jdim*kdim*sizeof(float));
  2083.  
  2084.  
  2085.   /* load up subset function for plotting */
  2086.   
  2087.   if(aero){
  2088.     if((number_Of_Functions_Read_In == 4 && b_2D) ||
  2089.        (number_Of_Functions_Read_In == 5 && !b_2D)){
  2090.       ii = 0;
  2091.       for (l = l_0; l <= l_m; l= l + l_i){
  2092.     for (k = k_0; k <= k_m; k= k + k_i){
  2093.       for (j = j_0; j <= j_m; j = j + j_i){
  2094.         i = l*jmax*kmax + k*jmax + j;
  2095.         
  2096.         switch(functionChoice){
  2097.         case 0:                                  /* Q1: Density    */
  2098.           functionH.f[ii] = solnhunk.functions[i];  
  2099.           break;
  2100.         case 1:                                  /* Q2: U Momentum */
  2101.           functionH.f[ii] = solnhunk.functions[i+numberofpoints];
  2102.           break;
  2103.         case 2:                                  /* Q3: V Momentum */
  2104.           functionH.f[ii] = solnhunk.functions[i+2*numberofpoints];
  2105.           break;
  2106.         case 3:                                  /* Q4: W Momentum */
  2107.           functionH.f[ii] = solnhunk.functions[i+3*numberofpoints];
  2108.           break;
  2109.         case 4:                                  /* Q5: Energy     */
  2110.           if(!b_2D)functionH.f[ii] = 
  2111.         solnhunk.functions[i+4*numberofpoints];
  2112.           if(b_2D)functionH.f[ii] = solnhunk.functions[i+3*numberofpoints];
  2113.           break;
  2114.         case 5:                                  /* Mach Number    */
  2115.           functionH.f[ii] = solnhunk.mach_number[i];
  2116.           break;
  2117.         case 6:                                  /* Pressure       */
  2118.           functionH.f[ii] = solnhunk.pressure[i];
  2119.           break;
  2120.         case 7:
  2121.           functionH.f[ii] =                      /* Cp             */
  2122.         2.0/(gamma*solnhunk.fsmach*solnhunk.fsmach) * 
  2123.           (solnhunk.pressure[i]*gamma - 1.);
  2124.           break;
  2125.         case 8:                                  /* U Velocity     */
  2126.           functionH.f[ii] = 
  2127.         solnhunk.functions[i+numberofpoints]/solnhunk.functions[i];
  2128.           break;
  2129.         case 9:                                  /* V Velocity     */
  2130.           functionH.f[ii] = 
  2131.         solnhunk.functions[i+2*numberofpoints]/solnhunk.functions[i];
  2132.           break;
  2133.         case 10:                                 /* W Velocity     */
  2134.           functionH.f[ii] = 
  2135.         solnhunk.functions[i+3*numberofpoints]/solnhunk.functions[i];
  2136.           break;
  2137.         }
  2138.         ii = ii+1;
  2139.       }
  2140.     }
  2141.       }
  2142.     }
  2143.     else{
  2144.       ii = 0;
  2145.       for (l = l_0; l <= l_m; l= l + l_i){
  2146.     for (k = k_0; k <= k_m; k= k + k_i){
  2147.       for (j = j_0; j <= j_m; j = j + j_i){
  2148.         i = l*jmax*kmax + k*jmax + j;
  2149.         functionH.f[ii] = 
  2150.           solnhunk.functions[i + functionChoice*numberofpoints];
  2151.         ii = ii+1;
  2152.       }
  2153.     }
  2154.       }
  2155.     }
  2156.   }
  2157.   
  2158.   if(!aero){
  2159.     ii = 0;
  2160.     for (l = l_0; l <= l_m; l= l + l_i){
  2161.       for (k = k_0; k <= k_m; k= k + k_i){
  2162.     for (j = j_0; j <= j_m; j = j + j_i){
  2163.       i = l*jmax*kmax + k*jmax + j;
  2164.       functionH.f[ii] = 
  2165.         solnhunk.functions[i + functionChoice*numberofpoints];
  2166.       ii = ii+1;
  2167.     }
  2168.       }
  2169.     }
  2170.   }
  2171.   
  2172.   
  2173.   [self findFunctionMinAndMax];
  2174.   [self resetFunctionMinMax:self];  
  2175.  
  2176.   return self;
  2177. }
  2178.  
  2179. - loadFunctionGrid:sender
  2180. {
  2181.   int  j, k, l, i, ii;
  2182.   BOOL b_2D = [self do2D3D];
  2183.   BOOL b_2D_grid = [self do2D3D_grid];
  2184.   int jdim,kdim,jmax,kmax,planeChoice;
  2185.   int j_0,j_i,j_m,k_0,k_i,k_m,l_0,l_i,l_m;
  2186.   int viewChoice = 
  2187.     [viewingTransformations selectedRow] + 
  2188.       4*[viewingTransformations selectedCol];
  2189.  
  2190.   if(b_2D == b_2D_grid){
  2191.     jdim = solnhunk.jmax;
  2192.     kdim = solnhunk.kmax;
  2193.     jmax = solnhunk.jmax;
  2194.     kmax = solnhunk.kmax;
  2195.     planeChoice = [chooseFunctionPlane selectedRow];}
  2196.   else{
  2197.     jdim = gridhunk.jmax;
  2198.     kdim = gridhunk.kmax;
  2199.     jmax = gridhunk.jmax;
  2200.     kmax = gridhunk.kmax;
  2201.     planeChoice = [chooseGridPlane selectedRow];}
  2202.  
  2203.   /* failsafe for 2d/3d */
  2204.   if(b_2D_grid){
  2205.     if(viewChoice != 0 && viewChoice != 4 && viewChoice != 3){
  2206.       NXBeep(); beepError = 18;
  2207.       viewChoice = 0;
  2208.       [viewingTransformations selectCellAt:viewChoice:0];
  2209.     }
  2210.     if(planeChoice != 2){
  2211.       NXBeep();  beepError = 19;
  2212.       planeChoice = 2;
  2213.       if(b_2D == b_2D_grid)[chooseFunctionPlane selectCellAt:planeChoice:0];
  2214.       if(b_2D != b_2D_grid)[chooseGridPlane selectCellAt:planeChoice:0];
  2215.     }
  2216.   }
  2217.  
  2218.  
  2219.   /* shift indices down 1  */
  2220.   if(b_2D == b_2D_grid){
  2221.     j_0 = [jFunctionMin intValueAt:0] - 1;
  2222.     j_i = [jFunctionInc intValueAt:0];
  2223.     j_m = [jFunctionMax intValueAt:0] - 1;
  2224.  
  2225.     k_0 = [kFunctionMin intValueAt:0] - 1;
  2226.     k_i = [kFunctionInc intValueAt:0];
  2227.     k_m = [kFunctionMax intValueAt:0] - 1;
  2228.  
  2229.     l_0 = [lFunctionMin intValueAt:0] - 1;
  2230.     l_i = [lFunctionInc intValueAt:0];
  2231.     l_m = [lFunctionMax intValueAt:0] - 1;
  2232.  
  2233.   /* failsafe, j or k can never be <=0 || >= max*/
  2234.     if(j_i <= 0 || j_i > solnhunk.jmax){
  2235.       NXBeep();  beepError = 21;
  2236.       j_i = 1;
  2237.       [jFunctionInc setIntValue:j_i at:0];
  2238.     }
  2239.     if(j_0 < 0 || j_0 > solnhunk.jmax-1){
  2240.       NXBeep();  beepError = 21;
  2241.       j_0 = 0;
  2242.       [jFunctionMin setIntValue:j_0+1 at:0];
  2243.     }
  2244.     if(j_m < 0 || j_m > solnhunk.jmax-1){
  2245.       NXBeep();  beepError = 21;
  2246.       j_m = solnhunk.jmax-1;
  2247.       [jFunctionMax setIntValue:j_m+1 at:0];
  2248.     }
  2249.     if(j_m < j_0 && planeChoice != 0){
  2250.       NXBeep();  beepError = 21;
  2251.       j_0 = 0;
  2252.       [jFunctionMin setIntValue:j_0+1 at:0];
  2253.       j_m = solnhunk.jmax-1;
  2254.       [jFunctionMax setIntValue:j_m+1 at:0];
  2255.     }
  2256.     
  2257.     if(k_i <= 0 || k_i > solnhunk.kmax){
  2258.       NXBeep();  beepError = 21;
  2259.       k_i = 1;
  2260.       [kFunctionInc setIntValue:k_i at:0];
  2261.     }
  2262.     if(k_0 < 0 || k_0 > solnhunk.kmax-1){
  2263.       NXBeep();  beepError = 21;
  2264.       k_0 = 0;
  2265.       [kFunctionMin setIntValue:k_0+1 at:0];
  2266.     }
  2267.     if(k_m < 0 || k_m > solnhunk.kmax-1){
  2268.       NXBeep();  beepError = 21;
  2269.       k_m = solnhunk.kmax-1;
  2270.       [kFunctionMax setIntValue:k_m+1 at:0];
  2271.     }
  2272.     if(k_m < k_0 && planeChoice != 1){
  2273.       NXBeep();  beepError = 21;
  2274.       k_0 = 0;
  2275.       [kFunctionMin setIntValue:k_0+1 at:0];
  2276.       k_m = solnhunk.kmax-1;
  2277.       [kFunctionMax setIntValue:k_m+1 at:0];
  2278.     }
  2279.     
  2280.     if(l_i <= 0 || l_i > solnhunk.lmax){
  2281.       NXBeep();  beepError = 21;
  2282.       l_i = 1;
  2283.       [lFunctionInc setIntValue:l_i at:0];
  2284.     }
  2285.     if(l_0 < 0 || l_0 > solnhunk.lmax-1){
  2286.       NXBeep();  beepError = 21;
  2287.       l_0 = 0;
  2288.       [lFunctionMin setIntValue:l_0+1 at:0];
  2289.     }
  2290.     if(l_m < 0 || l_m > solnhunk.lmax-1){
  2291.       NXBeep();  beepError = 21;
  2292.       l_m = solnhunk.lmax-1;
  2293.       [lFunctionMax setIntValue:l_m+1 at:0];
  2294.     }
  2295.     if(l_m < l_0 && planeChoice != 2){
  2296.       NXBeep();  beepError = 21;
  2297.       l_0 = 0;
  2298.       [lFunctionMin setIntValue:l_0+1 at:0];
  2299.       l_m = solnhunk.lmax-1;
  2300.     [lFunctionMax setIntValue:l_m+1 at:0];
  2301.     }
  2302.   
  2303.   }
  2304.   else{
  2305.     j_0 = [jGridMin intValueAt:0] - 1;
  2306.     j_i = [jGridInc intValueAt:0];
  2307.     j_m = [jGridMax intValueAt:0] - 1;
  2308.  
  2309.     k_0 = [kGridMin intValueAt:0] - 1;
  2310.     k_i = [kGridInc intValueAt:0];
  2311.     k_m = [kGridMax intValueAt:0] - 1;
  2312.  
  2313.     l_0 = [lGridMin intValueAt:0] - 1;
  2314.     l_i = [lGridInc intValueAt:0];
  2315.     l_m = [lGridMax intValueAt:0] - 1;
  2316.  
  2317.   /* failsafe, j or k can never be <=0 || >= max*/
  2318.     if(j_i <= 0 || j_i > solnhunk.jmax){
  2319.       NXBeep();  beepError = 21;
  2320.       j_i = 1;
  2321.       [jGridInc setIntValue:j_i at:0];
  2322.     }
  2323.     if(j_0 < 0 || j_0 > solnhunk.jmax-1){
  2324.       NXBeep();  beepError = 21;
  2325.       j_0 = 0;
  2326.       [jGridMin setIntValue:j_0+1 at:0];
  2327.     }
  2328.     if(j_m < 0 || j_m > solnhunk.jmax-1){
  2329.       NXBeep();  beepError = 21;
  2330.       j_m = solnhunk.jmax-1;
  2331.       [jGridMax setIntValue:j_m+1 at:0];
  2332.     }
  2333.     if(j_m < j_0 && planeChoice != 0){
  2334.       NXBeep();  beepError = 21;
  2335.       j_0 = 0;
  2336.       [jGridMin setIntValue:j_0+1 at:0];
  2337.       j_m = solnhunk.jmax-1;
  2338.       [jGridMax setIntValue:j_m+1 at:0];
  2339.     }
  2340.     
  2341.     if(k_i <= 0 || k_i > solnhunk.kmax){
  2342.       NXBeep();  beepError = 21;
  2343.       k_i = 1;
  2344.       [kGridInc setIntValue:k_i at:0];
  2345.     }
  2346.     if(k_0 < 0 || k_0 > solnhunk.kmax-1){
  2347.       NXBeep();  beepError = 21;
  2348.       k_0 = 0;
  2349.       [kGridMin setIntValue:k_0+1 at:0];
  2350.     }
  2351.     if(k_m < 0 || k_m > solnhunk.kmax-1){
  2352.       NXBeep();  beepError = 21;
  2353.       k_m = solnhunk.kmax-1;
  2354.       [kGridMax setIntValue:k_m+1 at:0];
  2355.     }
  2356.     if(k_m < k_0 && planeChoice != 1){
  2357.       NXBeep();  beepError = 21;
  2358.       k_0 = 0;
  2359.       [kGridMin setIntValue:k_0+1 at:0];
  2360.       k_m = solnhunk.kmax-1;
  2361.       [kGridMax setIntValue:k_m+1 at:0];
  2362.     }
  2363.     
  2364.     if(l_i <= 0 || l_i > solnhunk.lmax){
  2365.       NXBeep();  beepError = 21;
  2366.       l_i = 1;
  2367.       [lGridInc setIntValue:l_i at:0];
  2368.     }
  2369.     if(l_0 < 0 || l_0 > solnhunk.lmax-1){
  2370.       NXBeep();  beepError = 21;
  2371.       l_0 = 0;
  2372.       [lGridMin setIntValue:l_0+1 at:0];
  2373.     }
  2374.     if(l_m < 0 || l_m > solnhunk.lmax-1){
  2375.       NXBeep();  beepError = 21;
  2376.       l_m = solnhunk.lmax-1;
  2377.       [lGridMax setIntValue:l_m+1 at:0];
  2378.     }
  2379.     if(l_m < l_0 && planeChoice != 2){
  2380.       NXBeep();  beepError = 21;
  2381.       l_0 = 0;
  2382.       [lGridMin setIntValue:l_0+1 at:0];
  2383.       l_m = solnhunk.lmax-1;
  2384.     [lGridMax setIntValue:l_m+1 at:0];
  2385.     }
  2386.   
  2387.   }
  2388.  
  2389.   switch(planeChoice){
  2390.  
  2391.   case 0:
  2392.     jdim = (k_m - k_0)/k_i + 1;
  2393.     kdim = (l_m - l_0)/l_i + 1;
  2394.     j_m = j_0;
  2395.     [jFunctionMax setIntValue:j_m+1 at:0];
  2396.     j_i = 1;
  2397.     [jFunctionInc setIntValue:j_i at:0];
  2398.     break;
  2399.   case 1:
  2400.     jdim = (j_m - j_0)/j_i + 1;
  2401.     kdim = (l_m - l_0)/l_i + 1;
  2402.     k_m = k_0;
  2403.     [kFunctionMax setIntValue:k_m+1 at:0];
  2404.     k_i = 1;
  2405.     [kFunctionInc setIntValue:k_i at:0];
  2406.     break;
  2407.   case 2:
  2408.     jdim = (j_m - j_0)/j_i + 1;
  2409.     kdim = (k_m - k_0)/k_i + 1;
  2410.     l_m = l_0;
  2411.     [lFunctionMax setIntValue:l_m+1 at:0];
  2412.     l_i = 1;
  2413.     [lFunctionInc setIntValue:l_i at:0];
  2414.     break;
  2415.   }
  2416.  
  2417.   free((void *)functionH.x);
  2418.   free((void *)functionH.y);
  2419.  
  2420.   functionH.jmax = jdim;
  2421.   functionH.kmax = kdim;
  2422.   functionH.x =  (NXCoord *)malloc(jdim*kdim*sizeof(float));
  2423.   functionH.y =  (NXCoord *)malloc(jdim*kdim*sizeof(float));
  2424.  
  2425.  
  2426.   /* load up subset function grid for plotting */
  2427.   
  2428.   /*  load up grid */
  2429.   switch(viewChoice){
  2430.  
  2431.   case 0:
  2432.     ii = 0;
  2433.     for (l = l_0; l <= l_m; l= l + l_i){
  2434.       for (k = k_0; k <= k_m; k= k + k_i){
  2435.     for (j = j_0; j <= j_m; j = j + j_i){
  2436.       i = l*jmax*kmax + k*jmax + j;
  2437.       functionH.x[ii] = gridhunk.x[i];
  2438.       functionH.y[ii] = gridhunk.y[i];
  2439.       ii = ii+1;
  2440.     }
  2441.       }
  2442.     }
  2443.     break;
  2444.  
  2445.   case 1:
  2446.  
  2447.     ii = 0;
  2448.     for (l = l_0; l <= l_m; l= l + l_i){
  2449.       for (k = k_0; k <= k_m; k= k + k_i){
  2450.     for (j = j_0; j <= j_m; j = j + j_i){
  2451.       i = l*jmax*kmax + k*jmax + j;
  2452.       functionH.x[ii] = gridhunk.x[i];
  2453.       functionH.y[ii] = gridhunk.z[i];
  2454.       ii = ii+1;
  2455.     }
  2456.       }
  2457.     }
  2458.     break;
  2459.  
  2460.   case 2:
  2461.  
  2462.     ii = 0;
  2463.     for (l = l_0; l <= l_m; l= l + l_i){
  2464.       for (k = k_0; k <= k_m; k= k + k_i){
  2465.     for (j = j_0; j <= j_m; j = j + j_i){
  2466.       i = l*jmax*kmax + k*jmax + j;
  2467.       functionH.x[ii] = gridhunk.y[i];
  2468.       functionH.y[ii] = gridhunk.z[i];
  2469.       ii = ii+1;
  2470.     }
  2471.       }
  2472.     }
  2473.     break;
  2474.  
  2475.   case 3:
  2476.  
  2477.     ii = 0;
  2478.     for (l = l_0; l <= l_m; l= l + l_i){
  2479.       for (k = k_0; k <= k_m; k= k + k_i){
  2480.     for (j = j_0; j <= j_m; j = j + j_i){
  2481.       switch(planeChoice){
  2482.       case 2:
  2483.         functionH.x[ii] = (float)j+1;
  2484.         functionH.y[ii] = (float)k+1;
  2485.         break;
  2486.       case 0:
  2487.         functionH.x[ii] = (float)k+1;
  2488.         functionH.y[ii] = (float)l+1;
  2489.         break;
  2490.       case 1:
  2491.         functionH.x[ii] = (float)j+1;
  2492.         functionH.y[ii] = (float)l+1;
  2493.         break;
  2494.       }
  2495.       ii = ii+1;
  2496.     }
  2497.       }
  2498.     }
  2499.     break;
  2500.  
  2501.   case 4:
  2502.     ii = 0;
  2503.     for (l = l_0; l <= l_m; l= l + l_i){
  2504.       for (k = k_0; k <= k_m; k= k + k_i){
  2505.     for (j = j_0; j <= j_m; j = j + j_i){
  2506.       i = l*jmax*kmax + k*jmax + j;
  2507.       functionH.x[ii] = gridhunk.y[i];
  2508.       functionH.y[ii] = gridhunk.x[i];
  2509.       ii = ii+1;
  2510.     }
  2511.       }
  2512.     }
  2513.     break;
  2514.  
  2515.   case 5:
  2516.  
  2517.     ii = 0;
  2518.     for (l = l_0; l <= l_m; l= l + l_i){
  2519.       for (k = k_0; k <= k_m; k= k + k_i){
  2520.     for (j = j_0; j <= j_m; j = j + j_i){
  2521.       i = l*jmax*kmax + k*jmax + j;
  2522.       functionH.x[ii] = gridhunk.z[i];
  2523.       functionH.y[ii] = gridhunk.x[i];
  2524.       ii = ii+1;
  2525.     }
  2526.       }
  2527.     }
  2528.     break;
  2529.  
  2530.   case 6:
  2531.  
  2532.     ii = 0;
  2533.     for (l = l_0; l <= l_m; l= l + l_i){
  2534.       for (k = k_0; k <= k_m; k= k + k_i){
  2535.     for (j = j_0; j <= j_m; j = j + j_i){
  2536.       i = l*jmax*kmax + k*jmax + j;
  2537.       functionH.x[ii] = gridhunk.z[i];
  2538.       functionH.y[ii] = gridhunk.y[i];
  2539.       ii = ii+1;
  2540.     }
  2541.       }
  2542.     }
  2543.     break;
  2544.   }
  2545.  
  2546.  
  2547.   [self findFunctionGridMinAndMax];
  2548. /////  if(stateChangeFunction)[self resetFunctionGridMinMax:self];
  2549.   return self;
  2550. }
  2551.  
  2552. - whyTheBeep:sender
  2553. {
  2554.   switch(beepError){
  2555.   case 0:
  2556.     NXRunAlertPanel("The Beep Panel", 
  2557.       "BEEP BEEP, We All Need Some Info Sometime\n Just Click Why The Beep? whenever you hear BEEP\n                A Service Of NeXTcontour",
  2558.             "OK",NULL,NULL);
  2559.     break;
  2560.   case 1:
  2561.     NXRunAlertPanel("The Beep Happened Because", 
  2562.             "Can't animate without drawing function",
  2563.             "OK",NULL,NULL);
  2564.     break;
  2565.   case 2:
  2566.     NXRunAlertPanel("The Beep Happened Because", 
  2567.             "No grid available for plotting \n read in a Grid File",
  2568.             "OK",NULL,NULL);
  2569.     break;
  2570.   case 3:
  2571.     NXRunAlertPanel("The Beep Happened Because", 
  2572.         "No function available for plotting \n read in a Data File",
  2573.             "OK",NULL,NULL);
  2574.     break;
  2575.   case 4:
  2576.     NXRunAlertPanel("The Beep Happened Because", 
  2577.             "You Can't Plot With min = max \n Check min/max Subsets, Plane and Projection",
  2578.             "OK",NULL,NULL);
  2579.     break;
  2580.   case 11:
  2581.     NXRunAlertPanel("The Beep Happened Because", 
  2582.         "Viewing Choice Must Be XY or YX for 2D Cases \n I Fixed It For You",
  2583.             "OK",NULL,NULL);
  2584.     break;
  2585.   case 12:
  2586.     NXRunAlertPanel("The Beep Happened Because", 
  2587.         "Plane Choice Must Be l for 2D Cases \n I Fixed It For You",
  2588.             "OK",NULL,NULL);
  2589.     break;
  2590.   case 13:
  2591.     NXRunAlertPanel("The Beep Happened Because", 
  2592.    "Function Choice >  Number of Functions Available \n I Fixed It For You",
  2593.             "OK",NULL,NULL);
  2594.     break;
  2595.   case 14:
  2596.     NXRunAlertPanel("The Beep Happened Because", 
  2597.    "For 2D Cases You Can't Plot W or W-Momentum \n I Fixed It For You",
  2598.             "OK",NULL,NULL);
  2599.     break;
  2600.   case 15:
  2601.     NXRunAlertPanel("The Beep Happened Because", 
  2602.         "Viewing Choice Must Be XY or YX for 2D Cases \n I Fixed It For You",
  2603.             "OK",NULL,NULL);
  2604.     break;
  2605.   case 16:
  2606.     NXRunAlertPanel("The Beep Happened Because", 
  2607.         "Plane Choice Must Be l for 2D Cases \n I Fixed It For You",
  2608.             "OK",NULL,NULL);
  2609.     break;
  2610.   case 17:
  2611.     NXRunAlertPanel("The Beep Happened Because", 
  2612.    "For 2D Cases You Can't Plot W or W-Momentum \n I Fixed It For You",
  2613.             "OK",NULL,NULL);
  2614.     break;
  2615.   case 18:
  2616.     NXRunAlertPanel("The Beep Happened Because", 
  2617.         "Viewing Choice Must Be XY or YX for 2D Cases \n I Fixed It For You",
  2618.             "OK",NULL,NULL);
  2619.     break;
  2620.   case 19:
  2621.     NXRunAlertPanel("The Beep Happened Because", 
  2622.         "Plane Choice Must Be l for 2D Cases \n I Fixed It For You",
  2623.             "OK",NULL,NULL);
  2624.     break;
  2625.   case 20:
  2626.     NXRunAlertPanel("The Beep Happened Because", 
  2627.         "Indices Out Of Range For Grid Subsets\n I Fixed It For You",
  2628.             "OK",NULL,NULL);
  2629.     break;
  2630.   case 21:
  2631.     NXRunAlertPanel("The Beep Happened Because", 
  2632.         "Indices Out Of Range For Function Subsets\n I Fixed It For You",
  2633.             "OK",NULL,NULL);
  2634.     break;
  2635.   case 22:
  2636.     NXRunAlertPanel("The Beep Happened Because", 
  2637.         "You Need To Choose Plot Grid or Plot Function\n GO FOR IT!",
  2638.             "OK",NULL,NULL);
  2639.     break;
  2640.   case 23:
  2641.     NXRunAlertPanel("The Beep Happened Because", 
  2642.    "For 2D Cases You Can't Plot Z Coordnate Data Line\n I Fixed It For You",
  2643.             "OK",NULL,NULL);
  2644.     break;
  2645.   case 24:
  2646.     NXRunAlertPanel("The Beep Happened Because", 
  2647.    "For 2D Cases You Can't Plot l Coordnate Data Line\n I Fixed It For You",
  2648.             "OK",NULL,NULL);
  2649.     break;
  2650.   case 25:
  2651.     NXRunAlertPanel("The Beep Happened Because", 
  2652.    "Color Option Not Allow By Preferences \n Reset Preferences Or Use Black/Gray \n I Reset Line Color For Now",
  2653.             "OK",NULL,NULL);
  2654.     break;
  2655.   case 26:
  2656.     NXRunAlertPanel("The Beep Happened Because", 
  2657.    "You Can not animate with <= zero increment \n I Fixed It For You",
  2658.             "OK",NULL,NULL);
  2659.     break;
  2660.   case 27:
  2661.     NXRunAlertPanel("The Beep Happened Because", 
  2662.    "The number of funtions to be read in was checked \n previous warning panel took care of it for you",
  2663.             "OK",NULL,NULL);
  2664.     break;
  2665.   case 28:
  2666.     NXRunAlertPanel("The Beep Happened Because", 
  2667.    "You asked for an awful lot of list data \n The alert panel took care of it for you",
  2668.             "OK",NULL,NULL);
  2669.     break;
  2670.   }
  2671.   return self;
  2672. }
  2673.  
  2674. - (int)checkMinMax
  2675.   float xmin = [xyLimits floatValueAt:0];
  2676.   float xmax = [xyLimits floatValueAt:1];
  2677.   float ymin = [xyLimits floatValueAt:2];
  2678.   float ymax = [xyLimits floatValueAt:3];
  2679.   int error = 0;
  2680.  
  2681.   if(xmin == xmax){
  2682.     NXRunAlertPanel
  2683.       ("Min/Max Check", 
  2684.        "Plot Error xmin = xmax : Check min/max \n Subsets, Plane Choice and Projections", 
  2685.        "OK",NULL,NULL);
  2686.     error = 1;
  2687.   }
  2688.   if(ymin == ymax){
  2689.     NXRunAlertPanel
  2690.       ("Min/Max Check", 
  2691.        "Plot Error ymin = ymax : Check min/max \n Subsets, Plane Choice and Projections", 
  2692.        "OK",NULL,NULL);
  2693.     error = 1;
  2694.   }
  2695.  
  2696.   return error;
  2697. }
  2698.  
  2699. - writeOutLineData:sender 
  2700. {
  2701.   int  jdim = solnhunk.jmax;
  2702.   int  jmax = solnhunk.jmax;
  2703.   int  kmax = solnhunk.kmax;
  2704.   int  j, k, l, i, ii, i_minus;
  2705.   int j_0,j_i,j_m,k_0,k_i,k_m,l_0,l_i,l_m;
  2706.   int coordinateChoice = [absissaCoordinate selectedRow];
  2707.   int lineChoice = [chooseLineData selectedRow];
  2708.   int functionChoice = [functionMatrix selectedRow];
  2709.   BOOL b_2D = [self do2D3D];
  2710.   BOOL aero = [self doAeroDynamics];
  2711.   float gamma = 1.4;
  2712.   float xyData_save;
  2713.   int numberofpoints = solnhunk.jmax*solnhunk.kmax*solnhunk.lmax;
  2714.  
  2715.   /* failsafes for 2d/3d multiple vrs single functions*/
  2716.  
  2717.   if(!aero && functionChoice+1 > number_Of_Functions_Read_In ){
  2718.     NXBeep();    beepError = 13;        /* audible alert */
  2719.     functionChoice = 0;
  2720.     [functionMatrix selectCellAt:functionChoice:0];
  2721.   }
  2722.   if(aero){
  2723.     if((number_Of_Functions_Read_In != 4 && b_2D) ||
  2724.        (number_Of_Functions_Read_In != 5 && !b_2D)){
  2725.       if(functionChoice+1 > number_Of_Functions_Read_In ){
  2726.     NXBeep();    beepError = 13;        /* audible alert */
  2727.     functionChoice = 0;
  2728.     [functionMatrix selectCellAt:functionChoice:0];
  2729.       }
  2730.     }
  2731.   }
  2732.  
  2733.   if(b_2D){
  2734.     if((functionChoice == 3 || functionChoice == 10 )
  2735.        && (aero && number_Of_Functions_Read_In == 4)){
  2736.       NXBeep();    beepError = 14;    /* audible alert */
  2737.       functionChoice = 0;
  2738.       [functionMatrix selectCellAt:functionChoice:0];
  2739.     }
  2740.     if(coordinateChoice == 2 ){
  2741.       NXBeep();    beepError = 23;    /* audible alert */
  2742.       coordinateChoice = 0;
  2743.       [absissaCoordinate selectCellAt:coordinateChoice:0];
  2744.     }
  2745.     if(lineChoice == 2 ){
  2746.       NXBeep();    beepError = 24;    /* audible alert */
  2747.       lineChoice = 0;
  2748.       [chooseLineData selectCellAt:lineChoice:0];
  2749.     }
  2750.   }
  2751.  
  2752.  
  2753.   /* shift indices down 1  */
  2754.   j_0 = [jLineMin intValueAt:0] - 1;
  2755.   j_i = [jLineInc intValueAt:0];
  2756.   j_m = [jLineMax intValueAt:0] - 1;
  2757.  
  2758.   k_0 = [kLineMin intValueAt:0] - 1;
  2759.   k_i = [kLineInc intValueAt:0];
  2760.   k_m = [kLineMax intValueAt:0] - 1;
  2761.  
  2762.   l_0 = [lLineMin intValueAt:0] - 1;
  2763.   l_i = [lLineInc intValueAt:0];
  2764.   l_m = [lLineMax intValueAt:0] - 1;
  2765.   
  2766.  
  2767.   /* failsafe, j or k can never be <=0 || >= max*/
  2768.   if(j_i <= 0 || j_i > solnhunk.jmax){
  2769.     NXBeep();  beepError = 21;
  2770.     j_i = 1;
  2771.     [jLineInc setIntValue:j_i at:0];
  2772.   }
  2773.   if(j_0 < 0 || j_0 > solnhunk.jmax-1){
  2774.     NXBeep();  beepError = 21;
  2775.     j_0 = 0;
  2776.     [jLineMin setIntValue:j_0+1 at:0];
  2777.   }
  2778.   if(j_m < 0 || j_m > solnhunk.jmax-1){
  2779.     NXBeep();  beepError = 21;
  2780.     j_m = solnhunk.jmax-1;
  2781.     [jLineMax setIntValue:j_m+1 at:0];
  2782.   }
  2783.   if(j_m < j_0 && lineChoice == 0){
  2784.     NXBeep();  beepError = 21;
  2785.     j_0 = 0;
  2786.     [jLineMin setIntValue:j_0+1 at:0];
  2787.     j_m = solnhunk.jmax-1;
  2788.     [jLineMax setIntValue:j_m+1 at:0];
  2789.   }
  2790.  
  2791.   if(k_i <= 0 || k_i > solnhunk.kmax){
  2792.     NXBeep();  beepError = 21;
  2793.     k_i = 1;
  2794.     [kLineInc setIntValue:k_i at:0];
  2795.   }
  2796.   if(k_0 < 0 || k_0 > solnhunk.kmax-1){
  2797.     NXBeep();  beepError = 21;
  2798.     k_0 = 0;
  2799.     [kLineMin setIntValue:k_0+1 at:0];
  2800.   }
  2801.   if(k_m < 0 || k_m > solnhunk.kmax-1){
  2802.     NXBeep();  beepError = 21;
  2803.     k_m = solnhunk.kmax-1;
  2804.     [kLineMax setIntValue:k_m+1 at:0];
  2805.   }
  2806.   if(k_m < k_0 && lineChoice == 1){
  2807.     NXBeep();  beepError = 21;
  2808.     k_0 = 0;
  2809.     [kLineMin setIntValue:k_0+1 at:0];
  2810.     k_m = solnhunk.kmax-1;
  2811.     [kLineMax setIntValue:k_m+1 at:0];
  2812.   }
  2813.   
  2814.   if(l_i <= 0 || l_i > solnhunk.lmax){
  2815.     NXBeep();  beepError = 21;
  2816.     l_i = 1;
  2817.     [lLineInc setIntValue:l_i at:0];
  2818.   }
  2819.   if(l_0 < 0 || l_0 > solnhunk.lmax-1){
  2820.     NXBeep();  beepError = 21;
  2821.     l_0 = 0;
  2822.     [lLineMin setIntValue:l_0+1 at:0];
  2823.   }
  2824.   if(l_m < 0 || l_m > solnhunk.lmax-1){
  2825.     NXBeep();  beepError = 21;
  2826.     l_m = solnhunk.lmax-1;
  2827.     [lLineMax setIntValue:l_m+1 at:0];
  2828.   }
  2829.   if(l_m < l_0 && lineChoice == 2){
  2830.     NXBeep();  beepError = 21;
  2831.     l_0 = 0;
  2832.     [lLineMin setIntValue:l_0+1 at:0];
  2833.     l_m = solnhunk.lmax-1;
  2834.     [lLineMax setIntValue:l_m+1 at:0];
  2835.   }
  2836.  
  2837.  
  2838.   switch(lineChoice){
  2839.  
  2840.   case 0:
  2841.     jdim = (j_m - j_0)/j_i + 1;
  2842.     k_m = k_0;
  2843.     l_m = l_0;
  2844.     k_i = 1;
  2845.     l_i = 1;
  2846.     [kLineMax setIntValue:k_m+1 at:0];
  2847.     [lLineMax setIntValue:l_m+1 at:0];
  2848.     [kLineInc setIntValue:k_i at:0];
  2849.     [lLineInc setIntValue:l_i at:0];
  2850.     break;
  2851.   case 1:
  2852.     jdim = (k_m - k_0)/k_i + 1;
  2853.     j_m = j_0;
  2854.     l_m = l_0;
  2855.     j_i = 1;
  2856.     l_i = 1;
  2857.     [jLineMax setIntValue:j_m+1 at:0];
  2858.     [lLineMax setIntValue:l_m+1 at:0];
  2859.     [jLineInc setIntValue:j_i at:0];
  2860.     [lLineInc setIntValue:l_i at:0];
  2861.     break;
  2862.   case 2:
  2863.     jdim = (l_m - l_0)/l_i + 1;
  2864.     k_m = k_0;
  2865.     j_m = j_0;
  2866.     k_i = 1;
  2867.     j_i = 1;
  2868.     [kLineMax setIntValue:k_m+1 at:0];
  2869.     [jLineMax setIntValue:j_m+1 at:0];
  2870.     [kLineInc setIntValue:k_i at:0];
  2871.     [jLineInc setIntValue:j_i at:0];
  2872.     break;
  2873.   }
  2874.  
  2875.   free((void *)xyData.f);
  2876.   free((void *)xyData.x);
  2877.  
  2878.   xyData.jmax = jdim;
  2879.  
  2880.   xyData.x =  (NXCoord *)malloc(jdim*sizeof(float));
  2881.   xyData.f =  (NXCoord *)malloc(jdim*sizeof(float));
  2882.  
  2883.   if(coordinateChoice == 3){
  2884.     ii = 0;
  2885.     xyData_save = 0.0;
  2886.     i_minus = l_0*jmax*kmax + k_0*jmax + j_0;
  2887.     
  2888.     for (l = l_0; l <= l_m; l= l + l_i){
  2889.       for (k = k_0; k <= k_m; k= k + k_i){
  2890.     for (j = j_0; j <= j_m; j = j + j_i){
  2891.       i = l*jmax*kmax + k*jmax + j;
  2892.       if(b_2D){
  2893.         xyData.x[ii] = xyData_save + 
  2894.           sqrt(
  2895.            (gridhunk.x[i]-gridhunk.x[i_minus])*
  2896.            (gridhunk.x[i]-gridhunk.x[i_minus]) +
  2897.            (gridhunk.y[i]-gridhunk.y[i_minus])*
  2898.            (gridhunk.y[i]-gridhunk.y[i_minus]) );
  2899.       }
  2900.       if(!b_2D){
  2901.         xyData.x[ii] = xyData_save + 
  2902.           sqrt(
  2903.            (gridhunk.x[i]-gridhunk.x[i_minus])*
  2904.            (gridhunk.x[i]-gridhunk.x[i_minus]) +
  2905.            (gridhunk.y[i]-gridhunk.y[i_minus])*
  2906.            (gridhunk.y[i]-gridhunk.y[i_minus]) +
  2907.            (gridhunk.z[i]-gridhunk.z[i_minus])*
  2908.            (gridhunk.z[i]-gridhunk.z[i_minus]) );
  2909.       }
  2910.       i_minus = i;
  2911.       xyData_save = xyData.x[ii];
  2912.       ii = ii+1;
  2913.     }
  2914.       }
  2915.     }
  2916.   }
  2917.  
  2918.   ii = 0;
  2919.   for (l = l_0; l <= l_m; l= l + l_i){
  2920.     for (k = k_0; k <= k_m; k= k + k_i){
  2921.       for (j = j_0; j <= j_m; j = j + j_i){
  2922.     i = l*jmax*kmax + k*jmax + j;
  2923.  
  2924.     switch(coordinateChoice){
  2925.     case 0:
  2926.       xyData.x[ii] = gridhunk.x[i];
  2927.       break;
  2928.     case 1:
  2929.       xyData.x[ii] = gridhunk.y[i];
  2930.       break;
  2931.     case 2:
  2932.       xyData.x[ii] = gridhunk.z[i];
  2933.       break;
  2934.     case 3:
  2935.       break;
  2936.     case 4:
  2937.       if(lineChoice==0)xyData.x[ii] = j+1;
  2938.       if(lineChoice==1)xyData.x[ii] = k+1;
  2939.       if(lineChoice==2)xyData.x[ii] = l+1;
  2940.       break;
  2941.     }
  2942.  
  2943.     if(aero){
  2944.       switch(functionChoice){
  2945.       case 0:
  2946.         xyData.f[ii] = solnhunk.functions[i];
  2947.         break;
  2948.       case 1:
  2949.         xyData.f[ii] = solnhunk.functions[i+numberofpoints];
  2950.         break;
  2951.       case 2:
  2952.         xyData.f[ii] = solnhunk.functions[i+2*numberofpoints];
  2953.         break;
  2954.       case 3:
  2955.         xyData.f[ii] = solnhunk.functions[i+3*numberofpoints];
  2956.         break;
  2957.       case 4:
  2958.         if(!b_2D)xyData.f[ii] = solnhunk.functions[i+4*numberofpoints];
  2959.         if(b_2D)xyData.f[ii] = solnhunk.functions[i+3*numberofpoints];
  2960.         break;
  2961.       case 5:
  2962.         xyData.f[ii] = solnhunk.mach_number[i];
  2963.         break;
  2964.       case 6:
  2965.         xyData.f[ii] = solnhunk.pressure[i];
  2966.         break;
  2967.       case 7:
  2968.         xyData.f[ii] =
  2969.           2.0/(gamma*solnhunk.fsmach*solnhunk.fsmach) * 
  2970.         (solnhunk.pressure[i]*gamma - 1.);
  2971.         break;
  2972.       case 8:
  2973.         xyData.f[ii] = 
  2974.           solnhunk.functions[i+numberofpoints]/solnhunk.functions[i];
  2975.         break;
  2976.       case 9:
  2977.         xyData.f[ii] = 
  2978.           solnhunk.functions[i+2*numberofpoints]/solnhunk.functions[i];
  2979.         break;
  2980.       case 10:
  2981.         xyData.f[ii] = 
  2982.           solnhunk.functions[i+3*numberofpoints]/solnhunk.functions[i];
  2983.         break;
  2984.       }
  2985.     }
  2986.  
  2987.     if(!aero){
  2988.       xyData.f[ii] = 
  2989.         solnhunk.functions[i + functionChoice*numberofpoints];
  2990.     }
  2991.  
  2992.     ii = ii+1;
  2993.       }
  2994.     }
  2995.   }
  2996.  
  2997.   return self;
  2998. }
  2999.  
  3000. - (BOOL)appAcceptsAnotherFile:sender
  3001. /* Added by J. Gregory 9-Oct-91. */
  3002. {
  3003.     return YES;
  3004. }
  3005.  
  3006. - (int)app:sender openFile:(const char *)fullPath type:(const char *)aType
  3007. {
  3008.   if(gridIsReadIn && solutionIsReadIn)
  3009.     {gridIsReadIn = NO; solutionIsReadIn = NO;}
  3010.  
  3011.   if(!gridIsReadIn){
  3012.     [self openGridFile:(char *)fullPath];}
  3013.   else{
  3014.     [self openSolnFile:(char *)fullPath];}
  3015.     
  3016.   return YES;
  3017. }
  3018. /*
  3019.  * This function is called by the PlotView object during zooming.
  3020.  */
  3021. - stackOldMinMax:(float)xmin :(float)xmax :(float)ymin :(float)ymax
  3022. {
  3023.   oldMin = currentMin;        /* structure assignment */
  3024.   oldMax = currentMax;
  3025.   currentMin.x = xmin;
  3026.   currentMax.x = xmax;
  3027.   currentMin.y = ymin;
  3028.   currentMax.y = ymax;
  3029.   return self;
  3030. }
  3031.  
  3032. - previousView:sender
  3033. {
  3034.   NXPoint tmp;
  3035.  
  3036.   [self resetXmin:oldMin.x];
  3037.   [self resetXmax:oldMax.x];
  3038.   [self resetYmin:oldMin.y];
  3039.   [self resetYmax:oldMax.y];
  3040.   tmp        = oldMin;
  3041.   oldMin     = currentMin;
  3042.   currentMin = tmp;
  3043.   tmp        = oldMax;
  3044.   oldMax     = currentMax;
  3045.   currentMax = tmp;
  3046.   [self drawPlotButton:1];    /* display "Plotting" */
  3047.   [canvas display];
  3048.   [self drawPlotButton:0];    /* display "Plot" */
  3049.  
  3050.   return self;
  3051. }
  3052.  
  3053. // newTextView: is invoked in response to a new empty window request. It
  3054. // creates a new window containing a TextView. Note that we want new windows 
  3055. // to be offset from each other by some amount; hence the use of Rect.
  3056.  
  3057. #define g_ORIGX 150.0
  3058. #define g_ORIGY 200.0
  3059. static NXRect gRect = {{g_ORIGX, g_ORIGY},{900.0,600.0}};
  3060.  
  3061. - listGridData:sender
  3062. {   
  3063.   char data[64];
  3064.   const char *types[1];
  3065.   int length, max_length;
  3066.   char *s_data;
  3067.   static int window_number = 0;
  3068.  
  3069.   id newTextView;
  3070.  
  3071.   NXOffsetRect(&gRect, 20.0, -20.0);
  3072.   if (gRect.origin.y < 0) {
  3073.     gRect.origin.y = g_ORIGY;
  3074.     gRect.origin.x = g_ORIGX;
  3075.   }
  3076.   newTextView = [[TextView alloc] initFrame:&gRect];
  3077.   [[newTextView window] setDelegate:self];     
  3078.   window_number  = window_number + 1;
  3079.   sprintf(data, " Grid Data %d",window_number);
  3080.   [[newTextView window] setTitle:data];     
  3081.  
  3082.   theTextView = newTextView;
  3083.  
  3084.   pboardoutput = [Pasteboard new]; /* get the standard selection pasteboard */
  3085.  
  3086.   types[0] = NXAsciiPboardType;
  3087.   [pboardoutput declareTypes:types num:1 owner:NULL];
  3088.  
  3089.   sprintf(data, " Grid Data Output \n");
  3090.   [pboardoutput writeType:types[0] data:data length:strlen(data)+1];
  3091.   [[theTextView provideTextObject] paste:self];
  3092.   sprintf(data, " ---------------- \n");
  3093.   [pboardoutput writeType:types[0] data:data length:strlen(data)+1];
  3094.   [[theTextView provideTextObject] paste:self];
  3095.  
  3096.   data_stream = NXOpenMemory(NULL,0,NX_WRITEONLY);
  3097.  
  3098.   listGrid_Data = YES;
  3099.   [self listGridLoad:self];
  3100.   if(!listGrid_Data){
  3101.     [[newTextView window] close];     
  3102.     return self;
  3103.   }
  3104.   listGrid_Data = NO;
  3105.  
  3106.   NXGetMemoryBuffer(data_stream, &s_data, &length, &max_length);
  3107.  
  3108.   [pboardoutput declareTypes:&NXAsciiPboardType num:1 owner:self];
  3109.   [pboardoutput writeType:NXAsciiPboardType data:s_data length:length];
  3110.   NXCloseMemory(data_stream, NX_TRUNCATEBUFFER);
  3111.  
  3112.   [[theTextView provideTextObject] paste:self];
  3113.  
  3114.   return self;
  3115. }
  3116.  
  3117. #define f_ORIGX 200.0
  3118. #define f_ORIGY 150.0
  3119. static NXRect fRect = {{f_ORIGX, f_ORIGY},{500.0,600.0}};
  3120. - listFunctionData:sender
  3121. {   
  3122.   char data[64];
  3123.   const char *types[1];
  3124.   int length, max_length;
  3125.   char *s_data;
  3126.   static int window_number = 0;
  3127.   id newTextView;
  3128.  
  3129.   NXOffsetRect(&fRect, 20.0, -20.0);
  3130.   if (fRect.origin.y < 0) {
  3131.     fRect.origin.y = f_ORIGY;
  3132.     fRect.origin.x = f_ORIGX;
  3133.   }
  3134.   newTextView = [[TextView alloc] initFrame:&fRect];
  3135.   [[newTextView window] setDelegate:self];     
  3136.   window_number  = window_number + 1;
  3137.   sprintf(data, " Function Data %d",window_number);
  3138.   [[newTextView window] setTitle:data];     
  3139. //  [[newTextView window] setTitle:"FUNCTION"];     
  3140.  
  3141.   theTextView = newTextView;
  3142.  
  3143.   pboardoutput = [Pasteboard new]; /* get the standard selection pasteboard */
  3144.  
  3145.   types[0] = NXAsciiPboardType;
  3146.   [pboardoutput declareTypes:types num:1 owner:NULL];
  3147.  
  3148.   sprintf(data, " Function Data Output \n");
  3149.   [pboardoutput writeType:types[0] data:data length:strlen(data)+1];
  3150.   [[theTextView provideTextObject] paste:self];
  3151.   sprintf(data, " ---------------- \n");
  3152.   [pboardoutput writeType:types[0] data:data length:strlen(data)+1];
  3153.   [[theTextView provideTextObject] paste:self];
  3154.  
  3155.   data_stream = NXOpenMemory(NULL,0,NX_WRITEONLY);
  3156.  
  3157.   listSolution_Data = NO;
  3158.   listFunction_Data = YES;
  3159.   [self listFunction_SolutionLoad:self];
  3160.   // ask the text object to do a paste operation
  3161.   if(!listFunction_Data){
  3162.     [[newTextView window] close];     
  3163.     return self;
  3164.   }
  3165.   listFunction_Data = NO;
  3166.  
  3167.   NXGetMemoryBuffer(data_stream, &s_data, &length, &max_length);
  3168.  
  3169.   [pboardoutput declareTypes:&NXAsciiPboardType num:1 owner:self];
  3170.   [pboardoutput writeType:NXAsciiPboardType data:s_data length:length];
  3171.   NXCloseMemory(data_stream, NX_TRUNCATEBUFFER);
  3172.  
  3173.   [[theTextView provideTextObject] paste:self];
  3174.  
  3175.   return self;
  3176. }
  3177.  
  3178. #define s_ORIGX 100.0
  3179. #define s_ORIGY 100.0
  3180. static NXRect sRect = {{s_ORIGX, s_ORIGY},{1000.0,600.0}};
  3181. - listSolutionData:sender
  3182. {   
  3183.   char data[64];
  3184.   const char *types[1];
  3185.   int length, max_length;
  3186.   char *s_data;
  3187.   static int window_number = 0;
  3188.  
  3189.   id newTextView;
  3190.  
  3191.   NXOffsetRect(&sRect, 20.0, -20.0);
  3192.   if (sRect.origin.y < 0) {
  3193.     sRect.origin.y = s_ORIGY;
  3194.     sRect.origin.x = s_ORIGX;
  3195.   }
  3196.   newTextView = [[TextView alloc] initFrame:&sRect];
  3197.   [[newTextView window] setDelegate:self];     
  3198.   window_number  = window_number + 1;
  3199.   sprintf(data, " Solution Data %d",window_number);
  3200.   [[newTextView window] setTitle:data];     
  3201. //  [[newTextView window] setTitle:"SOLUTION"];     
  3202.  
  3203.   theTextView = newTextView;
  3204.  
  3205.   pboardoutput = [Pasteboard new]; /* get the standard selection pasteboard */
  3206.  
  3207.   types[0] = NXAsciiPboardType;
  3208.   [pboardoutput declareTypes:types num:1 owner:NULL];
  3209.  
  3210.   sprintf(data, " Solution Data Output \n");
  3211.   [pboardoutput writeType:types[0] data:data length:strlen(data)+1];
  3212.   [[theTextView provideTextObject] paste:self];
  3213.   sprintf(data, " ---------------- \n");
  3214.   [pboardoutput writeType:types[0] data:data length:strlen(data)+1];
  3215.   [[theTextView provideTextObject] paste:self];
  3216.  
  3217.   data_stream = NXOpenMemory(NULL,0,NX_WRITEONLY);
  3218.  
  3219.   listFunction_Data = NO;
  3220.   listSolution_Data = YES;
  3221.   [self listFunction_SolutionLoad:self];
  3222.   // ask the text object to do a paste operation
  3223.   if(!listSolution_Data){
  3224.     [[newTextView window] close];     
  3225.     return self;
  3226.   }
  3227.   listSolution_Data = NO;
  3228.  
  3229.   NXGetMemoryBuffer(data_stream, &s_data, &length, &max_length);
  3230.  
  3231.   [pboardoutput declareTypes:&NXAsciiPboardType num:1 owner:self];
  3232.   [pboardoutput writeType:NXAsciiPboardType data:s_data length:length];
  3233.   NXCloseMemory(data_stream, NX_TRUNCATEBUFFER);
  3234.  
  3235.   [[theTextView provideTextObject] paste:self];
  3236.  
  3237.   return self;
  3238. }
  3239.  
  3240. - listGridLoad:sender
  3241. {
  3242.   int  j, k, l, i, ii;
  3243.   int  jmax = gridhunk.jmax;
  3244.   int  kmax = gridhunk.kmax;
  3245.   int j_0,j_i,j_m,k_0,k_i,k_m,l_0,l_i,l_m;
  3246.   int planeChoice = [chooseGridPlane selectedRow];
  3247.   BOOL b_2D = [self do2D3D];
  3248.   int total_points = 100, errorAlert = 0;
  3249.  
  3250.   /* failsafe for 2d/3d */
  3251.   if(b_2D){
  3252.     if(planeChoice != 2){
  3253.       NXBeep(); beepError = 12;
  3254.       planeChoice = 2;
  3255.       [chooseGridPlane selectCellAt:planeChoice:0];
  3256.     }
  3257.   }
  3258.  
  3259.  
  3260.   /* shift indices down 1  */
  3261.   j_0 = [jGridMin intValueAt:0] - 1;
  3262.   j_i = [jGridInc intValueAt:0];
  3263.   j_m = [jGridMax intValueAt:0] - 1;
  3264.  
  3265.   k_0 = [kGridMin intValueAt:0] - 1;
  3266.   k_i = [kGridInc intValueAt:0];
  3267.   k_m = [kGridMax intValueAt:0] - 1;
  3268.  
  3269.   l_0 = [lGridMin intValueAt:0] - 1;
  3270.   l_i = [lGridInc intValueAt:0];
  3271.   l_m = [lGridMax intValueAt:0] - 1;
  3272.   
  3273.  
  3274.   /* failsafe, j or k can never be <=0 || >= max*/
  3275.   if(j_i <= 0 || j_i > gridhunk.jmax){
  3276.     NXBeep();  beepError = 20;
  3277.     j_i = 1;
  3278.     [jGridInc setIntValue:j_i at:0];
  3279.   }
  3280.   if(j_0 < 0 || j_0 > gridhunk.jmax-1){
  3281.     NXBeep();  beepError = 20;
  3282.     j_0 = 0;
  3283.     [jGridMin setIntValue:j_0+1 at:0];
  3284.   }
  3285.   if(j_m < 0 || j_m > gridhunk.jmax-1){
  3286.     NXBeep();  beepError = 20;
  3287.     j_m = gridhunk.jmax-1;
  3288.     [jGridMax setIntValue:j_m+1 at:0];
  3289.   }
  3290.   if(j_m < j_0 && planeChoice != 0){
  3291.     NXBeep();  beepError = 20;
  3292.     j_0 = 0;
  3293.     [jGridMin setIntValue:j_0+1 at:0];
  3294.     j_m = gridhunk.jmax-1;
  3295.     [jGridMax setIntValue:j_m+1 at:0];
  3296.   }
  3297.   
  3298.   if(k_i <= 0 || k_i > gridhunk.kmax){
  3299.     NXBeep();  beepError = 20;
  3300.     k_i = 1;
  3301.     [kGridInc setIntValue:k_i at:0];
  3302.   }
  3303.   if(k_0 < 0 || k_0 > gridhunk.kmax-1){
  3304.     NXBeep();  beepError = 20;
  3305.     k_0 = 0;
  3306.     [kGridMin setIntValue:k_0+1 at:0];
  3307.   }
  3308.   if(k_m < 0 || k_m > gridhunk.kmax-1){
  3309.     NXBeep();  beepError = 20;
  3310.     k_m = gridhunk.kmax-1;
  3311.     [kGridMax setIntValue:k_m+1 at:0];
  3312.   }
  3313.   if(k_m < k_0 && planeChoice != 1){
  3314.     NXBeep();  beepError = 20;
  3315.     k_0 = 0;
  3316.     [kGridMin setIntValue:k_0+1 at:0];
  3317.     k_m = gridhunk.kmax-1;
  3318.     [kGridMax setIntValue:k_m+1 at:0];
  3319.   }
  3320.   
  3321.   if(l_i <= 0 || l_i > gridhunk.lmax){
  3322.     NXBeep();  beepError = 20;
  3323.     l_i = 1;
  3324.     [lGridInc setIntValue:l_i at:0];
  3325.   }
  3326.   if(l_0 < 0 || l_0 > gridhunk.lmax-1){
  3327.     NXBeep();  beepError = 20;
  3328.     l_0 = 0;
  3329.     [lGridMin setIntValue:l_0+1 at:0];
  3330.   }
  3331.   if(l_m < 0 || l_m > gridhunk.lmax-1){
  3332.     NXBeep();  beepError = 20;
  3333.     l_m = gridhunk.lmax-1;
  3334.     [lGridMax setIntValue:l_m+1 at:0];
  3335.   }
  3336.   if(l_m < l_0 && planeChoice != 2){
  3337.     NXBeep();  beepError = 20;
  3338.     l_0 = 0;
  3339.     [lGridMin setIntValue:l_0+1 at:0];
  3340.     l_m = gridhunk.lmax-1;
  3341.     [lGridMax setIntValue:l_m+1 at:0];
  3342.   }
  3343.  
  3344.   total_points = ((j_m-j_0 + 1)/j_i)*((k_m-k_0 + 1)/k_i)*((l_m-l_0 + 1)/l_i);
  3345.   if(total_points > 100){
  3346.     NXBeep();    beepError = 28;        /* audible alert */
  3347.     errorAlert = 
  3348.       NXRunAlertPanel("The Number of Lines > 100", 
  3349.               "Number of Lines Of Data Exceeds 100 : You Can \n  Abort or Proceed (with possibly a Long Wait)", 
  3350.               "Continue?","ABORT?",NULL);
  3351.     if(errorAlert  == NX_ALERTALTERNATE){ listGrid_Data = NO; return self;}
  3352.   }
  3353.   if(total_points == 0){
  3354.     NXBeep();    beepError = 28;        /* audible alert */
  3355.     errorAlert = 
  3356.       NXRunAlertPanel("The Number of Lines = 0", 
  3357.               "Make Sure Grid Is Available: You Can \n  Abort or Proceed (with possibly a Long Wait)", 
  3358.               "Continue?","ABORT?",NULL);
  3359.     if(errorAlert  == NX_ALERTALTERNATE){ listGrid_Data = NO; return self;}
  3360.   }
  3361.  
  3362.   if(b_2D){
  3363.     ii = 0;
  3364.     for (l = l_0; l <= l_m; l= l + l_i){
  3365.       for (k = k_0; k <= k_m; k= k + k_i){
  3366.     for (j = j_0; j <= j_m; j = j + j_i){
  3367.       if(ii%100==0)
  3368.         NXPrintf(data_stream, 
  3369.              "\n   j    k    l         x               y \n");
  3370.       i = l*jmax*kmax + k*jmax + j;
  3371.       NXPrintf(data_stream, "%4d %4d %4d %16.10f %16.10f \n",
  3372.            j+1,k+1,l+1,gridhunk.x[i],gridhunk.y[i]);
  3373.       ii = ii+1;
  3374.     }
  3375.       }
  3376.     }
  3377.   }
  3378.  
  3379.   if(!b_2D){
  3380.     ii = 0;
  3381.     for (l = l_0; l <= l_m; l= l + l_i){
  3382.       for (k = k_0; k <= k_m; k= k + k_i){
  3383.     for (j = j_0; j <= j_m; j = j + j_i){
  3384.       if(ii%100==0)NXPrintf
  3385.         (data_stream, 
  3386.          "\n   j    k    l         x               y              z\n");
  3387.       i = l*jmax*kmax + k*jmax + j;
  3388.       NXPrintf(data_stream, "%4d %4d %4d %16.10f %16.10f %16.10f\n",
  3389.            j+1,k+1,l+1,gridhunk.x[i],gridhunk.y[i],gridhunk.z[i]);
  3390.       ii = ii+1;
  3391.     }
  3392.       }
  3393.     }
  3394.   }
  3395.  
  3396.   return self;
  3397. }
  3398.  
  3399. - listFunction_SolutionLoad:sender
  3400. {
  3401.   int  j, k, l, i, ii, n;
  3402.   int  jmax = solnhunk.jmax;
  3403.   int  kmax = solnhunk.kmax;
  3404.   int j_0,j_i,j_m,k_0,k_i,k_m,l_0,l_i,l_m;
  3405.   int planeChoice = [chooseFunctionPlane selectedRow];
  3406.   int functionChoice = [functionMatrix selectedRow];
  3407.   BOOL b_2D = [self do2D3D];
  3408.   BOOL aero = [self doAeroDynamics];
  3409.   float gamma = 1.4;
  3410.   int numberofpoints;
  3411.   int total_points = 100, errorAlert = 0;
  3412.   
  3413.   numberofpoints = solnhunk.jmax*solnhunk.kmax*solnhunk.lmax;
  3414.  
  3415.   /* failsafes for 2d/3d multiple vrs single functions*/
  3416.  
  3417.   if(!aero && functionChoice+1 > number_Of_Functions_Read_In ){
  3418.     NXBeep();    beepError = 13;        /* audible alert */
  3419.     functionChoice = 0;
  3420.     [functionMatrix selectCellAt:functionChoice:0];
  3421.   }
  3422.  
  3423.   if(aero){
  3424.     if((number_Of_Functions_Read_In != 4 && b_2D) ||
  3425.        (number_Of_Functions_Read_In != 5 && !b_2D)){
  3426.       if(functionChoice+1 > number_Of_Functions_Read_In ){
  3427.     NXBeep();    beepError = 13;        /* audible alert */
  3428.     functionChoice = 0;
  3429.     [functionMatrix selectCellAt:functionChoice:0];
  3430.       }
  3431.     }
  3432.   }
  3433.  
  3434.   if(b_2D){
  3435.     if((functionChoice == 3 || functionChoice == 10 )
  3436.        && (aero && number_Of_Functions_Read_In == 4)){
  3437.       NXBeep();    beepError = 14;    /* audible alert */
  3438.       functionChoice = 0;
  3439.       [functionMatrix selectCellAt:functionChoice:0];
  3440.     }
  3441.     if(planeChoice != 2){
  3442.       NXBeep(); beepError = 16;
  3443.       planeChoice = 2;
  3444.       [chooseFunctionPlane selectCellAt:planeChoice:0];
  3445.     }
  3446.   }
  3447.  
  3448.  
  3449.   /* shift indices down 1  */
  3450.   j_0 = [jFunctionMin intValueAt:0] - 1;
  3451.   j_i = [jFunctionInc intValueAt:0];
  3452.   j_m = [jFunctionMax intValueAt:0] - 1;
  3453.  
  3454.   k_0 = [kFunctionMin intValueAt:0] - 1;
  3455.   k_i = [kFunctionInc intValueAt:0];
  3456.   k_m = [kFunctionMax intValueAt:0] - 1;
  3457.  
  3458.   l_0 = [lFunctionMin intValueAt:0] - 1;
  3459.   l_i = [lFunctionInc intValueAt:0];
  3460.   l_m = [lFunctionMax intValueAt:0] - 1;
  3461.   
  3462.  
  3463.   /* failsafe, j or k can never be <=0 || >= max*/
  3464.   if(j_i <= 0 || j_i > solnhunk.jmax){
  3465.     NXBeep();  beepError = 21;
  3466.     j_i = 1;
  3467.     [jFunctionInc setIntValue:j_i at:0];
  3468.   }
  3469.   if(j_0 < 0 || j_0 > solnhunk.jmax-1){
  3470.     NXBeep();  beepError = 21;
  3471.     j_0 = 0;
  3472.     [jFunctionMin setIntValue:j_0+1 at:0];
  3473.   }
  3474.   if(j_m < 0 || j_m > solnhunk.jmax-1){
  3475.     NXBeep();  beepError = 21;
  3476.     j_m = solnhunk.jmax-1;
  3477.     [jFunctionMax setIntValue:j_m+1 at:0];
  3478.   }
  3479.   if(j_m < j_0 && planeChoice != 0){
  3480.     NXBeep();  beepError = 21;
  3481.     j_0 = 0;
  3482.     [jFunctionMin setIntValue:j_0+1 at:0];
  3483.     j_m = solnhunk.jmax-1;
  3484.     [jFunctionMax setIntValue:j_m+1 at:0];
  3485.   }
  3486.   
  3487.   if(k_i <= 0 || k_i > solnhunk.kmax){
  3488.     NXBeep();  beepError = 21;
  3489.     k_i = 1;
  3490.     [kFunctionInc setIntValue:k_i at:0];
  3491.   }
  3492.   if(k_0 < 0 || k_0 > solnhunk.kmax-1){
  3493.     NXBeep();  beepError = 21;
  3494.     k_0 = 0;
  3495.     [kFunctionMin setIntValue:k_0+1 at:0];
  3496.   }
  3497.   if(k_m < 0 || k_m > solnhunk.kmax-1){
  3498.     NXBeep();  beepError = 21;
  3499.     k_m = solnhunk.kmax-1;
  3500.     [kFunctionMax setIntValue:k_m+1 at:0];
  3501.   }
  3502.   if(k_m < k_0 && planeChoice != 1){
  3503.     NXBeep();  beepError = 21;
  3504.     k_0 = 0;
  3505.     [kFunctionMin setIntValue:k_0+1 at:0];
  3506.     k_m = solnhunk.kmax-1;
  3507.     [kFunctionMax setIntValue:k_m+1 at:0];
  3508.   }
  3509.   
  3510.   if(l_i <= 0 || l_i > solnhunk.lmax){
  3511.     NXBeep();  beepError = 21;
  3512.     l_i = 1;
  3513.     [lFunctionInc setIntValue:l_i at:0];
  3514.   }
  3515.   if(l_0 < 0 || l_0 > solnhunk.lmax-1){
  3516.     NXBeep();  beepError = 21;
  3517.     l_0 = 0;
  3518.     [lFunctionMin setIntValue:l_0+1 at:0];
  3519.   }
  3520.   if(l_m < 0 || l_m > solnhunk.lmax-1){
  3521.     NXBeep();  beepError = 21;
  3522.     l_m = solnhunk.lmax-1;
  3523.     [lFunctionMax setIntValue:l_m+1 at:0];
  3524.   }
  3525.   if(l_m < l_0 && planeChoice != 2){
  3526.     NXBeep();  beepError = 21;
  3527.     l_0 = 0;
  3528.     [lFunctionMin setIntValue:l_0+1 at:0];
  3529.     l_m = solnhunk.lmax-1;
  3530.     [lFunctionMax setIntValue:l_m+1 at:0];
  3531.   }
  3532.  
  3533.   total_points = ((j_m-j_0 + 1)/j_i)*((k_m-k_0 + 1)/k_i)*((l_m-l_0 + 1)/l_i);
  3534.   if(total_points > 100){
  3535.     NXBeep();    beepError = 28;        /* audible alert */
  3536.     errorAlert = NXRunAlertPanel("The Number of Lines > 100", 
  3537.                  "Number of Lines Of Data Exceeds 100 : You Can \n  Abort or Proceed (with possibly a Long Wait)", 
  3538.                  "Continue?","ABORT?",NULL);
  3539.     if(errorAlert  == NX_ALERTALTERNATE)
  3540.       { listFunction_Data = NO; listSolution_Data = NO; return self;}
  3541.   }
  3542.   if(total_points == 0){
  3543.     NXBeep();    beepError = 28;        /* audible alert */
  3544.     errorAlert = NXRunAlertPanel("The Number of Lines  = 0", 
  3545.                  "Make Sure Data Is Available : You Can \n  Abort or Proceed (with possibly a Long Wait)", 
  3546.                  "Continue?","ABORT?",NULL);
  3547.     if(errorAlert  == NX_ALERTALTERNATE)
  3548.       { listFunction_Data = NO; listSolution_Data = NO; return self;}
  3549.   }
  3550.  
  3551.   if(listFunction_Data){
  3552.  
  3553.     if(aero){
  3554.       switch(functionChoice){
  3555.       case 0:
  3556.     ii = 0;
  3557.     for (l = l_0; l <= l_m; l= l + l_i){
  3558.       for (k = k_0; k <= k_m; k= k + k_i){
  3559.         for (j = j_0; j <= j_m; j = j + j_i){
  3560.           if(ii%100==0)
  3561.         NXPrintf(data_stream, "\n   j    k    l     Density    \n");
  3562.           i = l*jmax*kmax + k*jmax + j;
  3563.           NXPrintf(data_stream, 
  3564.                "%4d %4d %4d %16.10f \n",
  3565.                j+1,k+1,l+1,solnhunk.functions[i]);
  3566.           ii = ii+1;
  3567.         }
  3568.       }
  3569.     }
  3570.     break;
  3571.       case 1:
  3572.     ii = 0;
  3573.     for (l = l_0; l <= l_m; l= l + l_i){
  3574.       for (k = k_0; k <= k_m; k= k + k_i){
  3575.         for (j = j_0; j <= j_m; j = j + j_i){
  3576.           if(ii%100==0)
  3577.         NXPrintf(data_stream, "\n   j    k    l     U Momentum   \n");
  3578.           i = l*jmax*kmax + k*jmax + j;
  3579.           NXPrintf(data_stream, 
  3580.                "%4d %4d %4d %16.10f \n",
  3581.                j+1,k+1,l+1,solnhunk.functions[i+numberofpoints]);
  3582.           ii = ii+1;
  3583.         }
  3584.       }
  3585.     }
  3586.     break;
  3587.       case 2:
  3588.     ii = 0;
  3589.     for (l = l_0; l <= l_m; l= l + l_i){
  3590.       for (k = k_0; k <= k_m; k= k + k_i){
  3591.         for (j = j_0; j <= j_m; j = j + j_i){
  3592.           if(ii%100==0)
  3593.         NXPrintf(data_stream, "\n   j    k    l     V Momentum   \n");
  3594.           i = l*jmax*kmax + k*jmax + j;
  3595.           NXPrintf(data_stream, 
  3596.                "%4d %4d %4d %16.10f \n",
  3597.                j+1,k+1,l+1,solnhunk.functions[i+2*numberofpoints]);
  3598.           ii = ii+1;
  3599.         }
  3600.       }
  3601.     }
  3602.     break;
  3603.       case 3:
  3604.     ii = 0;
  3605.     for (l = l_0; l <= l_m; l= l + l_i){
  3606.       for (k = k_0; k <= k_m; k= k + k_i){
  3607.         for (j = j_0; j <= j_m; j = j + j_i){
  3608.           if(ii%100==0)
  3609.         NXPrintf(data_stream, "\n   j    k    l     W Momentum   \n");
  3610.           i = l*jmax*kmax + k*jmax + j;
  3611.           NXPrintf(data_stream, 
  3612.                "%4d %4d %4d %16.10f \n",
  3613.                j+1,k+1,l+1,solnhunk.functions[i+3*numberofpoints]);
  3614.           ii = ii+1;
  3615.         }
  3616.       }
  3617.     }
  3618.     break;
  3619.       case 4:
  3620.     ii = 0;
  3621.     for (l = l_0; l <= l_m; l= l + l_i){
  3622.       for (k = k_0; k <= k_m; k= k + k_i){
  3623.         for (j = j_0; j <= j_m; j = j + j_i){
  3624.           if(ii%100==0)
  3625.         NXPrintf(data_stream, "\n   j    k    l     Energy   \n");
  3626.           i = l*jmax*kmax + k*jmax + j;
  3627.           if(!b_2D)NXPrintf(data_stream, 
  3628.                "%4d %4d %4d %16.10f \n",
  3629.                j+1,k+1,l+1,solnhunk.functions[i+4*numberofpoints]);
  3630.           if(b_2D)NXPrintf(data_stream, 
  3631.                "%4d %4d %4d %16.10f \n",
  3632.                j+1,k+1,l+1,solnhunk.functions[i+3*numberofpoints]);
  3633.           ii = ii+1;
  3634.         }
  3635.       }
  3636.     }
  3637.     break;
  3638.       case 5:
  3639.     ii = 0;
  3640.     for (l = l_0; l <= l_m; l= l + l_i){
  3641.       for (k = k_0; k <= k_m; k= k + k_i){
  3642.         for (j = j_0; j <= j_m; j = j + j_i){
  3643.           if(ii%100==0)
  3644.         NXPrintf(data_stream, "\n   j    k    l     Mach Number   \n");
  3645.           i = l*jmax*kmax + k*jmax + j;
  3646.           NXPrintf(data_stream, 
  3647.                "%4d %4d %4d %16.10f \n",
  3648.                j+1,k+1,l+1,solnhunk.mach_number[i]);
  3649.           ii = ii+1;
  3650.         }
  3651.       }
  3652.     }
  3653.     break;
  3654.       case 6:
  3655.     ii = 0;
  3656.     for (l = l_0; l <= l_m; l= l + l_i){
  3657.       for (k = k_0; k <= k_m; k= k + k_i){
  3658.         for (j = j_0; j <= j_m; j = j + j_i){
  3659.           if(ii%100==0)
  3660.         NXPrintf(data_stream, "\n   j    k    l     Pressure   \n");
  3661.           i = l*jmax*kmax + k*jmax + j;
  3662.           NXPrintf(data_stream, 
  3663.                "%4d %4d %4d %16.10f \n",
  3664.                j+1,k+1,l+1,solnhunk.pressure[i]);
  3665.           ii = ii+1;
  3666.         }
  3667.       }
  3668.     }
  3669.     break;
  3670.       case 7:
  3671.     ii = 0;
  3672.     for (l = l_0; l <= l_m; l= l + l_i){
  3673.       for (k = k_0; k <= k_m; k= k + k_i){
  3674.         for (j = j_0; j <= j_m; j = j + j_i){
  3675.           if(ii%100==0)
  3676.         NXPrintf(data_stream, "\n   j    k    l     Cp   \n");
  3677.           i = l*jmax*kmax + k*jmax + j;
  3678.           NXPrintf(data_stream, 
  3679.                "%4d %4d %4d %16.10f \n",
  3680.                j+1,k+1,l+1,
  3681.                2.0/(gamma*solnhunk.fsmach*solnhunk.fsmach) * 
  3682.                (solnhunk.pressure[i]*gamma - 1.));
  3683.           ii = ii+1;
  3684.         }
  3685.       }
  3686.     }
  3687.     break;
  3688.       case 8:
  3689.     ii = 0;
  3690.     for (l = l_0; l <= l_m; l= l + l_i){
  3691.       for (k = k_0; k <= k_m; k= k + k_i){
  3692.         for (j = j_0; j <= j_m; j = j + j_i){
  3693.           if(ii%100==0)
  3694.         NXPrintf(data_stream, "\n   j    k    l     U Velocity   \n");
  3695.           i = l*jmax*kmax + k*jmax + j;
  3696.           NXPrintf(data_stream, 
  3697.                "%4d %4d %4d %16.10f \n",
  3698.                j+1,k+1,l+1,
  3699.                solnhunk.functions[i+numberofpoints]/
  3700.                solnhunk.functions[i]);
  3701.           ii = ii+1;
  3702.         }
  3703.       }
  3704.     }
  3705.     break;
  3706.       case 9:
  3707.     ii = 0;
  3708.     for (l = l_0; l <= l_m; l= l + l_i){
  3709.       for (k = k_0; k <= k_m; k= k + k_i){
  3710.         for (j = j_0; j <= j_m; j = j + j_i){
  3711.           if(ii%100==0)
  3712.         NXPrintf(data_stream, "\n   j    k    l     V Velocity   \n");
  3713.           i = l*jmax*kmax + k*jmax + j;
  3714.           NXPrintf(data_stream, 
  3715.                "%4d %4d %4d %16.10f \n",
  3716.                j+1,k+1,l+1,
  3717.                solnhunk.functions[i+2*numberofpoints]
  3718.                /solnhunk.functions[i]);
  3719.           ii = ii+1;
  3720.         }
  3721.       }
  3722.     }
  3723.     break;
  3724.       case 10:
  3725.     ii = 0;
  3726.     for (l = l_0; l <= l_m; l= l + l_i){
  3727.       for (k = k_0; k <= k_m; k= k + k_i){
  3728.         for (j = j_0; j <= j_m; j = j + j_i){
  3729.           if(ii%100==0)
  3730.         NXPrintf(data_stream, "\n   j    k    l     W Velocity   \n");
  3731.           i = l*jmax*kmax + k*jmax + j;
  3732.           NXPrintf(data_stream, 
  3733.                "%4d %4d %4d %16.10f \n",
  3734.                j+1,k+1,l+1,
  3735.                solnhunk.functions[i+3*numberofpoints]/
  3736.                solnhunk.functions[i]);
  3737.           ii = ii+1;
  3738.         }
  3739.       }
  3740.     }
  3741.     break;
  3742.       }
  3743.     }
  3744.     if(!aero){
  3745.       ii = 0;
  3746.       for (l = l_0; l <= l_m; l= l + l_i){
  3747.     for (k = k_0; k <= k_m; k= k + k_i){
  3748.       for (j = j_0; j <= j_m; j = j + j_i){
  3749.           if(ii%100==0)
  3750.         NXPrintf(data_stream, "\n   j    k    l     Function %d \n",
  3751.              functionChoice+1);
  3752.         i = l*jmax*kmax + k*jmax + j;
  3753.         NXPrintf(data_stream, 
  3754.              "%4d %4d %4d %16.10f \n",
  3755.              j+1,k+1,l+1,
  3756.              solnhunk.functions[i+functionChoice*numberofpoints]);
  3757.         ii = ii+1;
  3758.       }
  3759.     }
  3760.       }
  3761.     }
  3762.   }
  3763.  
  3764.   if(listSolution_Data && b_2D && aero){
  3765.     ii = 0;
  3766.     for (l = l_0; l <= l_m; l= l + l_i){
  3767.       for (k = k_0; k <= k_m; k= k + k_i){
  3768.     for (j = j_0; j <= j_m; j = j + j_i){
  3769.       if(ii%100==0)NXPrintf(data_stream, 
  3770.              "\n   j    k    l         Q1               Q2             Q3             Q4\n");
  3771.       i = l*jmax*kmax + k*jmax + j;
  3772.       NXPrintf(data_stream, 
  3773.            "%4d %4d %4d %16.10f %16.10f %16.10f %16.10f\n",
  3774.            j+1,k+1,l+1,
  3775.            solnhunk.functions[i],
  3776.            solnhunk.functions[i+numberofpoints],
  3777.            solnhunk.functions[i+numberofpoints*2],
  3778.            solnhunk.functions[i+numberofpoints*3]);
  3779.       ii = ii+1;
  3780.     }
  3781.       }
  3782.     }
  3783.   }
  3784.  
  3785.   if(listSolution_Data && !b_2D && aero){
  3786.     ii = 0;
  3787.     for (l = l_0; l <= l_m; l= l + l_i){
  3788.       for (k = k_0; k <= k_m; k= k + k_i){
  3789.     for (j = j_0; j <= j_m; j = j + j_i){
  3790.       if(ii%100==0)NXPrintf(data_stream, 
  3791.              "\n   j    k    l         Q1               Q2             Q3             Q4             Q5\n");
  3792.       i = l*jmax*kmax + k*jmax + j;
  3793.       NXPrintf(data_stream, 
  3794.            "%4d %4d %4d %16.10f %16.10f %16.10f %16.10f %16.10f\n",
  3795.            j+1,k+1,l+1,
  3796.            solnhunk.functions[i],
  3797.            solnhunk.functions[i+numberofpoints],
  3798.            solnhunk.functions[i+numberofpoints*2],
  3799.            solnhunk.functions[i+numberofpoints*3],
  3800.            solnhunk.functions[i+numberofpoints*4]);
  3801.       ii = ii+1;
  3802.     }
  3803.       }
  3804.     }
  3805.   }
  3806.   if(listSolution_Data && !aero){
  3807.     ii = 0;
  3808.     for (l = l_0; l <= l_m; l= l + l_i){
  3809.       for (k = k_0; k <= k_m; k= k + k_i){
  3810.     for (j = j_0; j <= j_m; j = j + j_i){
  3811.       if(ii%100==0)NXPrintf(data_stream, 
  3812.              "\n   n    j    k    l  \n");
  3813.       i = l*jmax*kmax + k*jmax + j;      
  3814.       for(n = 0; n < number_Of_Functions_Read_In; n = n+1){
  3815.         NXPrintf(data_stream, 
  3816.              "Q %4d %4d %4d %4d %16.10f \n",
  3817.              n+1, j+1,k+1,l+1,solnhunk.functions[i+numberofpoints*n]);
  3818.       }
  3819.       ii = ii+1;
  3820.     }
  3821.       }
  3822.     }
  3823.   }
  3824.  
  3825.   return self;
  3826. }
  3827.  
  3828. - setWindowSize:sender
  3829. {
  3830.   NXRect fullFrame,currentFrame;
  3831.   
  3832.   NXSetRect(&fullFrame, 114.0, 0.0, 930.0, 830.0);
  3833.  
  3834.   [canvasWindow getFrame:¤tFrame];
  3835.  
  3836.   if(!NXEqualRect(¤tFrame, &fullFrame))[canvasWindow getFrame:&oldFrame];
  3837.  
  3838.   if([chooseScreenSize state])[canvasWindow placeWindow:&fullFrame];
  3839.   if(![chooseScreenSize state])[canvasWindow placeWindow:&oldFrame];
  3840.  
  3841.   [canvasWindow orderFront:self];
  3842.  
  3843.   [self drawPlotButton:1];    /* display "Plotting" */
  3844.   [canvas display];
  3845.   [self drawPlotButton:0];    /* display "Plot" */
  3846.  
  3847.   return self;
  3848. }
  3849.  
  3850. @end
  3851.  
  3852.